Compare commits
48 Commits
cli
...
ic3-featur
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d39139004
|
||
|
|
2658c39d0c
|
||
|
|
ce9c5baf27
|
||
|
|
f29a8b0e6d
|
||
|
|
eff47608f5
|
||
|
362446c5ed
|
|||
|
3930212d5d
|
|||
|
|
dfe9107112 | ||
|
|
ba5e449569 | ||
|
|
709bb708d3 | ||
|
|
87c1d161fc | ||
|
|
82284947ee | ||
|
|
8d4d6b7bfe | ||
|
|
7421e6d989 | ||
|
|
a1e0e5f720 | ||
|
|
c21afaa846 | ||
|
|
f0abb9ffbf | ||
|
|
8ca7f99098 | ||
| 6f9cd952d4 | |||
|
abb3cf3076
|
|||
|
40b0af0063
|
|||
| 976adf2b66 | |||
| 53cc4b9e9e | |||
|
51f62f039b
|
|||
|
42cc783887
|
|||
| ed7109270f | |||
| abd233ce65 | |||
| 215c39000b | |||
| c4d97b6537 | |||
| 0834400c05 | |||
| 463d14d2b5 | |||
| 6a52166901 | |||
| d7c2ad3dde | |||
| f54bf1dc34 | |||
| 644c04c133 | |||
| 8006e3efbc | |||
| b60d2b6186 | |||
| 8f2a0b53e4 | |||
| 70dd8502f4 | |||
| 5b977289e7 | |||
| 7b3af95f3d | |||
|
4d78a9b2c5
|
|||
|
ec59a83379
|
|||
| 54bf3f55a0 | |||
| 14f404ffe3 | |||
|
0e1d2fe50a
|
|||
|
ada8c322da
|
|||
|
84d2bfef20
|
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -1903,8 +1903,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "submissions-api"
|
name = "submissions-api"
|
||||||
version = "0.7.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ services:
|
|||||||
"--auth-rpc-host","authrpc:8081",
|
"--auth-rpc-host","authrpc:8081",
|
||||||
"--data-rpc-host","dataservice:9000",
|
"--data-rpc-host","dataservice:9000",
|
||||||
]
|
]
|
||||||
|
env_file:
|
||||||
|
- ../auth-compose/strafesnet_staging.env
|
||||||
depends_on:
|
depends_on:
|
||||||
- authrpc
|
- authrpc
|
||||||
- nats
|
- nats
|
||||||
|
|||||||
@@ -65,6 +65,53 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/error:
|
||||||
|
post:
|
||||||
|
summary: Validator posts an error to the audit log
|
||||||
|
operationId: createMapfixAuditError
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
- name: ErrorMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/checklist:
|
||||||
|
post:
|
||||||
|
summary: Validator posts a checklist to the audit log
|
||||||
|
operationId: createMapfixAuditCheckList
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CheckList'
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/mapfixes/{MapfixID}/status/validator-submitted:
|
/mapfixes/{MapfixID}/status/validator-submitted:
|
||||||
post:
|
post:
|
||||||
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
|
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
|
||||||
@@ -116,13 +163,6 @@ paths:
|
|||||||
- Mapfixes
|
- Mapfixes
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/MapfixID'
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
- name: ErrorMessage
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 0
|
|
||||||
maxLength: 4096
|
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -157,13 +197,6 @@ paths:
|
|||||||
- Mapfixes
|
- Mapfixes
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/MapfixID'
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
- name: ErrorMessage
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 0
|
|
||||||
maxLength: 4096
|
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -270,6 +303,53 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/error:
|
||||||
|
post:
|
||||||
|
summary: Validator posts an error to the audit log
|
||||||
|
operationId: createSubmissionAuditError
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
- name: ErrorMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/checklist:
|
||||||
|
post:
|
||||||
|
summary: Validator posts a checklist to the audit log
|
||||||
|
operationId: createSubmissionAuditCheckList
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CheckList'
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions/{SubmissionID}/status/validator-submitted:
|
/submissions/{SubmissionID}/status/validator-submitted:
|
||||||
post:
|
post:
|
||||||
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
|
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
|
||||||
@@ -321,13 +401,6 @@ paths:
|
|||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
- name: ErrorMessage
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 0
|
|
||||||
maxLength: 4096
|
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -362,13 +435,6 @@ paths:
|
|||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/SubmissionID'
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
- name: ErrorMessage
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 0
|
|
||||||
maxLength: 4096
|
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -847,6 +913,25 @@ components:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
|
Check:
|
||||||
|
required:
|
||||||
|
- Name
|
||||||
|
- Summary
|
||||||
|
- Passed
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
Name:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
Summary:
|
||||||
|
type: string
|
||||||
|
maxLength: 4096
|
||||||
|
Passed:
|
||||||
|
type: boolean
|
||||||
|
CheckList:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Check"
|
||||||
Error:
|
Error:
|
||||||
description: Represents error object
|
description: Represents error object
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
108
openapi.yaml
108
openapi.yaml
@@ -114,6 +114,13 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 4
|
maximum: 4
|
||||||
|
description: >
|
||||||
|
Sort order:
|
||||||
|
* `0` - Disabled
|
||||||
|
* `1` - DisplayNameAscending
|
||||||
|
* `2` - DisplayNameDescending
|
||||||
|
* `3` - DateAscending
|
||||||
|
* `4` - DateDescending
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -151,6 +158,34 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
|
/maps/{MapID}/location:
|
||||||
|
get:
|
||||||
|
summary: Get location of asset
|
||||||
|
operationId: getMapAssetLocation
|
||||||
|
tags:
|
||||||
|
- Maps
|
||||||
|
parameters:
|
||||||
|
- name: MapID
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
text/plain:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
maxLength: 1024
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
/mapfixes:
|
/mapfixes:
|
||||||
get:
|
get:
|
||||||
summary: Get list of mapfixes
|
summary: Get list of mapfixes
|
||||||
@@ -178,6 +213,11 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 1
|
minimum: 1
|
||||||
maximum: 5
|
maximum: 5
|
||||||
|
description: >
|
||||||
|
Game ID:
|
||||||
|
* `1` - Bhop
|
||||||
|
* `2` - Surf
|
||||||
|
* `5` - FlyTrials
|
||||||
- name: Sort
|
- name: Sort
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
@@ -185,6 +225,13 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 4
|
maximum: 4
|
||||||
|
description: >
|
||||||
|
Sort order:
|
||||||
|
* `0` - Disabled
|
||||||
|
* `1` - DisplayNameAscending
|
||||||
|
* `2` - DisplayNameDescending
|
||||||
|
* `3` - DateAscending
|
||||||
|
* `4` - DateDescending
|
||||||
- name: Submitter
|
- name: Submitter
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
@@ -210,6 +257,24 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 9
|
maximum: 9
|
||||||
|
description: >
|
||||||
|
// Phase: Creation
|
||||||
|
* `0` - UnderConstruction
|
||||||
|
* `1` - ChangesRequested
|
||||||
|
|
||||||
|
// Phase: Review
|
||||||
|
* `2` - Submitting
|
||||||
|
* `3` - Submitted
|
||||||
|
|
||||||
|
// Phase: Testing
|
||||||
|
* `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
|
||||||
|
* `5` - Validating
|
||||||
|
* `6` - Validated
|
||||||
|
* `7` - Uploading
|
||||||
|
|
||||||
|
// Phase: Final MapfixStatus
|
||||||
|
* `8` - Uploaded // uploaded to the group, but pending release
|
||||||
|
* `9` - Rejected
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -384,10 +449,10 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
/mapfixes/{MapfixID}/status/bypass-submit:
|
/mapfixes/{MapfixID}/status/trigger-submit-unchecked:
|
||||||
post:
|
post:
|
||||||
summary: Role Reviewer changes status from ChangesRequested -> Submitted
|
summary: Role Reviewer changes status from ChangesRequested -> Submitting
|
||||||
operationId: actionMapfixBypassSubmit
|
operationId: actionMapfixTriggerSubmitUnchecked
|
||||||
tags:
|
tags:
|
||||||
- Mapfixes
|
- Mapfixes
|
||||||
parameters:
|
parameters:
|
||||||
@@ -602,6 +667,11 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 1
|
minimum: 1
|
||||||
maximum: 5
|
maximum: 5
|
||||||
|
description: >
|
||||||
|
Game ID:
|
||||||
|
* `1` - Bhop
|
||||||
|
* `2` - Surf
|
||||||
|
* `5` - FlyTrials
|
||||||
- name: Sort
|
- name: Sort
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
@@ -609,6 +679,13 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 4
|
maximum: 4
|
||||||
|
description: >
|
||||||
|
Sort order:
|
||||||
|
* `0` - Disabled
|
||||||
|
* `1` - DisplayNameAscending
|
||||||
|
* `2` - DisplayNameDescending
|
||||||
|
* `3` - DateAscending
|
||||||
|
* `4` - DateDescending
|
||||||
- name: Submitter
|
- name: Submitter
|
||||||
in: query
|
in: query
|
||||||
schema:
|
schema:
|
||||||
@@ -634,6 +711,25 @@ paths:
|
|||||||
format: int32
|
format: int32
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 10
|
maximum: 10
|
||||||
|
description: >
|
||||||
|
// Phase: Creation
|
||||||
|
* `0` - UnderConstruction
|
||||||
|
* `1` - ChangesRequested
|
||||||
|
|
||||||
|
// Phase: Review
|
||||||
|
* `2` - Submitting
|
||||||
|
* `3` - Submitted
|
||||||
|
|
||||||
|
// Phase: Testing
|
||||||
|
* `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
|
||||||
|
* `5` - Validating
|
||||||
|
* `6` - Validated
|
||||||
|
* `7` - Uploading
|
||||||
|
* `8` - Uploaded // uploaded to the group, but pending release
|
||||||
|
|
||||||
|
// Phase: Final SubmissionStatus
|
||||||
|
* `9` - Rejected
|
||||||
|
* `10` - Released
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Successful response
|
description: Successful response
|
||||||
@@ -833,10 +929,10 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Error"
|
$ref: "#/components/schemas/Error"
|
||||||
/submissions/{SubmissionID}/status/bypass-submit:
|
/submissions/{SubmissionID}/status/trigger-submit-unchecked:
|
||||||
post:
|
post:
|
||||||
summary: Role Reviewer changes status from ChangesRequested -> Submitted
|
summary: Role Reviewer changes status from ChangesRequested -> Submitting
|
||||||
operationId: actionSubmissionBypassSubmit
|
operationId: actionSubmissionTriggerSubmitUnchecked
|
||||||
tags:
|
tags:
|
||||||
- Submissions
|
- Submissions
|
||||||
parameters:
|
parameters:
|
||||||
|
|||||||
@@ -35,12 +35,6 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/reset-validating
|
// POST /mapfixes/{MapfixID}/status/reset-validating
|
||||||
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
|
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
|
||||||
// ActionMapfixBypassSubmit invokes actionMapfixBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/bypass-submit
|
|
||||||
ActionMapfixBypassSubmit(ctx context.Context, params ActionMapfixBypassSubmitParams) error
|
|
||||||
// ActionMapfixReject invokes actionMapfixReject operation.
|
// ActionMapfixReject invokes actionMapfixReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -78,6 +72,12 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
||||||
ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error
|
ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error
|
||||||
|
// ActionMapfixTriggerSubmitUnchecked invokes actionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-submit-unchecked
|
||||||
|
ActionMapfixTriggerSubmitUnchecked(ctx context.Context, params ActionMapfixTriggerSubmitUncheckedParams) error
|
||||||
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -102,12 +102,6 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/reset-validating
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
// ActionSubmissionBypassSubmit invokes actionSubmissionBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/bypass-submit
|
|
||||||
ActionSubmissionBypassSubmit(ctx context.Context, params ActionSubmissionBypassSubmitParams) error
|
|
||||||
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -145,6 +139,12 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-submit
|
// POST /submissions/{SubmissionID}/status/trigger-submit
|
||||||
ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error
|
ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error
|
||||||
|
// ActionSubmissionTriggerSubmitUnchecked invokes actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-submit-unchecked
|
||||||
|
ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params ActionSubmissionTriggerSubmitUncheckedParams) error
|
||||||
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -223,6 +223,12 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// GET /maps/{MapID}
|
// GET /maps/{MapID}
|
||||||
GetMap(ctx context.Context, params GetMapParams) (*Map, error)
|
GetMap(ctx context.Context, params GetMapParams) (*Map, error)
|
||||||
|
// GetMapAssetLocation invokes getMapAssetLocation operation.
|
||||||
|
//
|
||||||
|
// Get location of asset.
|
||||||
|
//
|
||||||
|
// GET /maps/{MapID}/location
|
||||||
|
GetMapAssetLocation(ctx context.Context, params GetMapAssetLocationParams) (GetMapAssetLocationOK, error)
|
||||||
// GetMapfix invokes getMapfix operation.
|
// GetMapfix invokes getMapfix operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
@@ -530,130 +536,6 @@ func (c *Client) sendActionMapfixAccepted(ctx context.Context, params ActionMapf
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixBypassSubmit invokes actionMapfixBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/bypass-submit
|
|
||||||
func (c *Client) ActionMapfixBypassSubmit(ctx context.Context, params ActionMapfixBypassSubmitParams) error {
|
|
||||||
_, err := c.sendActionMapfixBypassSubmit(ctx, params)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) sendActionMapfixBypassSubmit(ctx context.Context, params ActionMapfixBypassSubmitParams) (res *ActionMapfixBypassSubmitNoContent, err error) {
|
|
||||||
otelAttrs := []attribute.KeyValue{
|
|
||||||
otelogen.OperationID("actionMapfixBypassSubmit"),
|
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
|
||||||
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/bypass-submit"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, ActionMapfixBypassSubmitOperation,
|
|
||||||
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] = "/mapfixes/"
|
|
||||||
{
|
|
||||||
// Encode "MapfixID" parameter.
|
|
||||||
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
|
||||||
Param: "MapfixID",
|
|
||||||
Style: uri.PathStyleSimple,
|
|
||||||
Explode: false,
|
|
||||||
})
|
|
||||||
if err := func() error {
|
|
||||||
return e.EncodeValue(conv.Int64ToString(params.MapfixID))
|
|
||||||
}(); 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/bypass-submit"
|
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
|
||||||
|
|
||||||
stage = "EncodeRequest"
|
|
||||||
r, err := ht.NewRequest(ctx, "POST", u)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "create request")
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
type bitset = [1]uint8
|
|
||||||
var satisfied bitset
|
|
||||||
{
|
|
||||||
stage = "Security:CookieAuth"
|
|
||||||
switch err := c.securityCookieAuth(ctx, ActionMapfixBypassSubmitOperation, r); {
|
|
||||||
case err == nil: // if NO error
|
|
||||||
satisfied[0] |= 1 << 0
|
|
||||||
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
|
|
||||||
// Skip this security.
|
|
||||||
default:
|
|
||||||
return res, errors.Wrap(err, "security \"CookieAuth\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok := func() bool {
|
|
||||||
nextRequirement:
|
|
||||||
for _, requirement := range []bitset{
|
|
||||||
{0b00000001},
|
|
||||||
} {
|
|
||||||
for i, mask := range requirement {
|
|
||||||
if satisfied[i]&mask != mask {
|
|
||||||
continue nextRequirement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}(); !ok {
|
|
||||||
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 := decodeActionMapfixBypassSubmitResponse(resp)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "decode response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixReject invokes actionMapfixReject operation.
|
// ActionMapfixReject invokes actionMapfixReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -1399,6 +1281,130 @@ func (c *Client) sendActionMapfixTriggerSubmit(ctx context.Context, params Actio
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionMapfixTriggerSubmitUnchecked invokes actionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-submit-unchecked
|
||||||
|
func (c *Client) ActionMapfixTriggerSubmitUnchecked(ctx context.Context, params ActionMapfixTriggerSubmitUncheckedParams) error {
|
||||||
|
_, err := c.sendActionMapfixTriggerSubmitUnchecked(ctx, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendActionMapfixTriggerSubmitUnchecked(ctx context.Context, params ActionMapfixTriggerSubmitUncheckedParams) (res *ActionMapfixTriggerSubmitUncheckedNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("actionMapfixTriggerSubmitUnchecked"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/trigger-submit-unchecked"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, ActionMapfixTriggerSubmitUncheckedOperation,
|
||||||
|
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] = "/mapfixes/"
|
||||||
|
{
|
||||||
|
// Encode "MapfixID" parameter.
|
||||||
|
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
||||||
|
Param: "MapfixID",
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
if err := func() error {
|
||||||
|
return e.EncodeValue(conv.Int64ToString(params.MapfixID))
|
||||||
|
}(); 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/trigger-submit-unchecked"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeRequest"
|
||||||
|
r, err := ht.NewRequest(ctx, "POST", u)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "create request")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
type bitset = [1]uint8
|
||||||
|
var satisfied bitset
|
||||||
|
{
|
||||||
|
stage = "Security:CookieAuth"
|
||||||
|
switch err := c.securityCookieAuth(ctx, ActionMapfixTriggerSubmitUncheckedOperation, r); {
|
||||||
|
case err == nil: // if NO error
|
||||||
|
satisfied[0] |= 1 << 0
|
||||||
|
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
|
||||||
|
// Skip this security.
|
||||||
|
default:
|
||||||
|
return res, errors.Wrap(err, "security \"CookieAuth\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok := func() bool {
|
||||||
|
nextRequirement:
|
||||||
|
for _, requirement := range []bitset{
|
||||||
|
{0b00000001},
|
||||||
|
} {
|
||||||
|
for i, mask := range requirement {
|
||||||
|
if satisfied[i]&mask != mask {
|
||||||
|
continue nextRequirement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}(); !ok {
|
||||||
|
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 := decodeActionMapfixTriggerSubmitUncheckedResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -1895,130 +1901,6 @@ func (c *Client) sendActionSubmissionAccepted(ctx context.Context, params Action
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionBypassSubmit invokes actionSubmissionBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/bypass-submit
|
|
||||||
func (c *Client) ActionSubmissionBypassSubmit(ctx context.Context, params ActionSubmissionBypassSubmitParams) error {
|
|
||||||
_, err := c.sendActionSubmissionBypassSubmit(ctx, params)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) sendActionSubmissionBypassSubmit(ctx context.Context, params ActionSubmissionBypassSubmitParams) (res *ActionSubmissionBypassSubmitNoContent, err error) {
|
|
||||||
otelAttrs := []attribute.KeyValue{
|
|
||||||
otelogen.OperationID("actionSubmissionBypassSubmit"),
|
|
||||||
semconv.HTTPRequestMethodKey.String("POST"),
|
|
||||||
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/bypass-submit"),
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, ActionSubmissionBypassSubmitOperation,
|
|
||||||
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/bypass-submit"
|
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
|
||||||
|
|
||||||
stage = "EncodeRequest"
|
|
||||||
r, err := ht.NewRequest(ctx, "POST", u)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "create request")
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
type bitset = [1]uint8
|
|
||||||
var satisfied bitset
|
|
||||||
{
|
|
||||||
stage = "Security:CookieAuth"
|
|
||||||
switch err := c.securityCookieAuth(ctx, ActionSubmissionBypassSubmitOperation, r); {
|
|
||||||
case err == nil: // if NO error
|
|
||||||
satisfied[0] |= 1 << 0
|
|
||||||
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
|
|
||||||
// Skip this security.
|
|
||||||
default:
|
|
||||||
return res, errors.Wrap(err, "security \"CookieAuth\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok := func() bool {
|
|
||||||
nextRequirement:
|
|
||||||
for _, requirement := range []bitset{
|
|
||||||
{0b00000001},
|
|
||||||
} {
|
|
||||||
for i, mask := range requirement {
|
|
||||||
if satisfied[i]&mask != mask {
|
|
||||||
continue nextRequirement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}(); !ok {
|
|
||||||
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 := decodeActionSubmissionBypassSubmitResponse(resp)
|
|
||||||
if err != nil {
|
|
||||||
return res, errors.Wrap(err, "decode response")
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -2764,6 +2646,130 @@ func (c *Client) sendActionSubmissionTriggerSubmit(ctx context.Context, params A
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionTriggerSubmitUnchecked invokes actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-submit-unchecked
|
||||||
|
func (c *Client) ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params ActionSubmissionTriggerSubmitUncheckedParams) error {
|
||||||
|
_, err := c.sendActionSubmissionTriggerSubmitUnchecked(ctx, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params ActionSubmissionTriggerSubmitUncheckedParams) (res *ActionSubmissionTriggerSubmitUncheckedNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("actionSubmissionTriggerSubmitUnchecked"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/trigger-submit-unchecked"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, ActionSubmissionTriggerSubmitUncheckedOperation,
|
||||||
|
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/trigger-submit-unchecked"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeRequest"
|
||||||
|
r, err := ht.NewRequest(ctx, "POST", u)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "create request")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
type bitset = [1]uint8
|
||||||
|
var satisfied bitset
|
||||||
|
{
|
||||||
|
stage = "Security:CookieAuth"
|
||||||
|
switch err := c.securityCookieAuth(ctx, ActionSubmissionTriggerSubmitUncheckedOperation, r); {
|
||||||
|
case err == nil: // if NO error
|
||||||
|
satisfied[0] |= 1 << 0
|
||||||
|
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
|
||||||
|
// Skip this security.
|
||||||
|
default:
|
||||||
|
return res, errors.Wrap(err, "security \"CookieAuth\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok := func() bool {
|
||||||
|
nextRequirement:
|
||||||
|
for _, requirement := range []bitset{
|
||||||
|
{0b00000001},
|
||||||
|
} {
|
||||||
|
for i, mask := range requirement {
|
||||||
|
if satisfied[i]&mask != mask {
|
||||||
|
continue nextRequirement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}(); !ok {
|
||||||
|
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 := decodeActionSubmissionTriggerSubmitUncheckedResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -4266,6 +4272,130 @@ func (c *Client) sendGetMap(ctx context.Context, params GetMapParams) (res *Map,
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMapAssetLocation invokes getMapAssetLocation operation.
|
||||||
|
//
|
||||||
|
// Get location of asset.
|
||||||
|
//
|
||||||
|
// GET /maps/{MapID}/location
|
||||||
|
func (c *Client) GetMapAssetLocation(ctx context.Context, params GetMapAssetLocationParams) (GetMapAssetLocationOK, error) {
|
||||||
|
res, err := c.sendGetMapAssetLocation(ctx, params)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendGetMapAssetLocation(ctx context.Context, params GetMapAssetLocationParams) (res GetMapAssetLocationOK, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("getMapAssetLocation"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("GET"),
|
||||||
|
semconv.HTTPRouteKey.String("/maps/{MapID}/location"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, GetMapAssetLocationOperation,
|
||||||
|
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] = "/maps/"
|
||||||
|
{
|
||||||
|
// Encode "MapID" parameter.
|
||||||
|
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
||||||
|
Param: "MapID",
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
if err := func() error {
|
||||||
|
return e.EncodeValue(conv.Int64ToString(params.MapID))
|
||||||
|
}(); 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] = "/location"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeRequest"
|
||||||
|
r, err := ht.NewRequest(ctx, "GET", u)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "create request")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
type bitset = [1]uint8
|
||||||
|
var satisfied bitset
|
||||||
|
{
|
||||||
|
stage = "Security:CookieAuth"
|
||||||
|
switch err := c.securityCookieAuth(ctx, GetMapAssetLocationOperation, r); {
|
||||||
|
case err == nil: // if NO error
|
||||||
|
satisfied[0] |= 1 << 0
|
||||||
|
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
|
||||||
|
// Skip this security.
|
||||||
|
default:
|
||||||
|
return res, errors.Wrap(err, "security \"CookieAuth\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok := func() bool {
|
||||||
|
nextRequirement:
|
||||||
|
for _, requirement := range []bitset{
|
||||||
|
{0b00000001},
|
||||||
|
} {
|
||||||
|
for i, mask := range requirement {
|
||||||
|
if satisfied[i]&mask != mask {
|
||||||
|
continue nextRequirement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}(); !ok {
|
||||||
|
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 := decodeGetMapAssetLocationResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMapfix invokes getMapfix operation.
|
// GetMapfix invokes getMapfix operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,58 +6,59 @@ package api
|
|||||||
type OperationName = string
|
type OperationName = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
|
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
|
||||||
ActionMapfixBypassSubmitOperation OperationName = "ActionMapfixBypassSubmit"
|
ActionMapfixRejectOperation OperationName = "ActionMapfixReject"
|
||||||
ActionMapfixRejectOperation OperationName = "ActionMapfixReject"
|
ActionMapfixRequestChangesOperation OperationName = "ActionMapfixRequestChanges"
|
||||||
ActionMapfixRequestChangesOperation OperationName = "ActionMapfixRequestChanges"
|
ActionMapfixResetSubmittingOperation OperationName = "ActionMapfixResetSubmitting"
|
||||||
ActionMapfixResetSubmittingOperation OperationName = "ActionMapfixResetSubmitting"
|
ActionMapfixRetryValidateOperation OperationName = "ActionMapfixRetryValidate"
|
||||||
ActionMapfixRetryValidateOperation OperationName = "ActionMapfixRetryValidate"
|
ActionMapfixRevokeOperation OperationName = "ActionMapfixRevoke"
|
||||||
ActionMapfixRevokeOperation OperationName = "ActionMapfixRevoke"
|
ActionMapfixTriggerSubmitOperation OperationName = "ActionMapfixTriggerSubmit"
|
||||||
ActionMapfixTriggerSubmitOperation OperationName = "ActionMapfixTriggerSubmit"
|
ActionMapfixTriggerSubmitUncheckedOperation OperationName = "ActionMapfixTriggerSubmitUnchecked"
|
||||||
ActionMapfixTriggerUploadOperation OperationName = "ActionMapfixTriggerUpload"
|
ActionMapfixTriggerUploadOperation OperationName = "ActionMapfixTriggerUpload"
|
||||||
ActionMapfixTriggerValidateOperation OperationName = "ActionMapfixTriggerValidate"
|
ActionMapfixTriggerValidateOperation OperationName = "ActionMapfixTriggerValidate"
|
||||||
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
|
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
|
||||||
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
||||||
ActionSubmissionBypassSubmitOperation OperationName = "ActionSubmissionBypassSubmit"
|
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
||||||
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
||||||
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
ActionSubmissionResetSubmittingOperation OperationName = "ActionSubmissionResetSubmitting"
|
||||||
ActionSubmissionResetSubmittingOperation OperationName = "ActionSubmissionResetSubmitting"
|
ActionSubmissionRetryValidateOperation OperationName = "ActionSubmissionRetryValidate"
|
||||||
ActionSubmissionRetryValidateOperation OperationName = "ActionSubmissionRetryValidate"
|
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
||||||
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
ActionSubmissionTriggerSubmitOperation OperationName = "ActionSubmissionTriggerSubmit"
|
||||||
ActionSubmissionTriggerSubmitOperation OperationName = "ActionSubmissionTriggerSubmit"
|
ActionSubmissionTriggerSubmitUncheckedOperation OperationName = "ActionSubmissionTriggerSubmitUnchecked"
|
||||||
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
||||||
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
||||||
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
CreateMapfixOperation OperationName = "CreateMapfix"
|
CreateMapfixOperation OperationName = "CreateMapfix"
|
||||||
CreateMapfixAuditCommentOperation OperationName = "CreateMapfixAuditComment"
|
CreateMapfixAuditCommentOperation OperationName = "CreateMapfixAuditComment"
|
||||||
CreateScriptOperation OperationName = "CreateScript"
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
CreateSubmissionOperation OperationName = "CreateSubmission"
|
CreateSubmissionOperation OperationName = "CreateSubmission"
|
||||||
CreateSubmissionAdminOperation OperationName = "CreateSubmissionAdmin"
|
CreateSubmissionAdminOperation OperationName = "CreateSubmissionAdmin"
|
||||||
CreateSubmissionAuditCommentOperation OperationName = "CreateSubmissionAuditComment"
|
CreateSubmissionAuditCommentOperation OperationName = "CreateSubmissionAuditComment"
|
||||||
DeleteScriptOperation OperationName = "DeleteScript"
|
DeleteScriptOperation OperationName = "DeleteScript"
|
||||||
DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy"
|
DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy"
|
||||||
GetMapOperation OperationName = "GetMap"
|
GetMapOperation OperationName = "GetMap"
|
||||||
GetMapfixOperation OperationName = "GetMapfix"
|
GetMapAssetLocationOperation OperationName = "GetMapAssetLocation"
|
||||||
GetOperationOperation OperationName = "GetOperation"
|
GetMapfixOperation OperationName = "GetMapfix"
|
||||||
GetScriptOperation OperationName = "GetScript"
|
GetOperationOperation OperationName = "GetOperation"
|
||||||
GetScriptPolicyOperation OperationName = "GetScriptPolicy"
|
GetScriptOperation OperationName = "GetScript"
|
||||||
GetSubmissionOperation OperationName = "GetSubmission"
|
GetScriptPolicyOperation OperationName = "GetScriptPolicy"
|
||||||
ListMapfixAuditEventsOperation OperationName = "ListMapfixAuditEvents"
|
GetSubmissionOperation OperationName = "GetSubmission"
|
||||||
ListMapfixesOperation OperationName = "ListMapfixes"
|
ListMapfixAuditEventsOperation OperationName = "ListMapfixAuditEvents"
|
||||||
ListMapsOperation OperationName = "ListMaps"
|
ListMapfixesOperation OperationName = "ListMapfixes"
|
||||||
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
ListMapsOperation OperationName = "ListMaps"
|
||||||
ListScriptsOperation OperationName = "ListScripts"
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
ListSubmissionAuditEventsOperation OperationName = "ListSubmissionAuditEvents"
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
ListSubmissionsOperation OperationName = "ListSubmissions"
|
ListSubmissionAuditEventsOperation OperationName = "ListSubmissionAuditEvents"
|
||||||
ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions"
|
ListSubmissionsOperation OperationName = "ListSubmissions"
|
||||||
SessionRolesOperation OperationName = "SessionRoles"
|
ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions"
|
||||||
SessionUserOperation OperationName = "SessionUser"
|
SessionRolesOperation OperationName = "SessionRoles"
|
||||||
SessionValidateOperation OperationName = "SessionValidate"
|
SessionUserOperation OperationName = "SessionUser"
|
||||||
SetMapfixCompletedOperation OperationName = "SetMapfixCompleted"
|
SessionValidateOperation OperationName = "SessionValidate"
|
||||||
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
SetMapfixCompletedOperation OperationName = "SetMapfixCompleted"
|
||||||
UpdateMapfixModelOperation OperationName = "UpdateMapfixModel"
|
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
||||||
UpdateScriptOperation OperationName = "UpdateScript"
|
UpdateMapfixModelOperation OperationName = "UpdateMapfixModel"
|
||||||
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
UpdateScriptOperation OperationName = "UpdateScript"
|
||||||
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
|
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
||||||
|
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -98,89 +98,6 @@ func decodeActionMapfixAcceptedParams(args [1]string, argsEscaped bool, r *http.
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixBypassSubmitParams is parameters of actionMapfixBypassSubmit operation.
|
|
||||||
type ActionMapfixBypassSubmitParams struct {
|
|
||||||
// The unique identifier for a mapfix.
|
|
||||||
MapfixID int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackActionMapfixBypassSubmitParams(packed middleware.Parameters) (params ActionMapfixBypassSubmitParams) {
|
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "MapfixID",
|
|
||||||
In: "path",
|
|
||||||
}
|
|
||||||
params.MapfixID = packed[key].(int64)
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeActionMapfixBypassSubmitParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixBypassSubmitParams, _ error) {
|
|
||||||
// Decode path: MapfixID.
|
|
||||||
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: "MapfixID",
|
|
||||||
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.MapfixID = c
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := func() error {
|
|
||||||
if err := (validate.Int{
|
|
||||||
MinSet: true,
|
|
||||||
Min: 0,
|
|
||||||
MaxSet: false,
|
|
||||||
Max: 0,
|
|
||||||
MinExclusive: false,
|
|
||||||
MaxExclusive: false,
|
|
||||||
MultipleOfSet: false,
|
|
||||||
MultipleOf: 0,
|
|
||||||
}).Validate(int64(params.MapfixID)); err != nil {
|
|
||||||
return errors.Wrap(err, "int")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return validate.ErrFieldRequired
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return params, &ogenerrors.DecodeParamError{
|
|
||||||
Name: "MapfixID",
|
|
||||||
In: "path",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixRejectParams is parameters of actionMapfixReject operation.
|
// ActionMapfixRejectParams is parameters of actionMapfixReject operation.
|
||||||
type ActionMapfixRejectParams struct {
|
type ActionMapfixRejectParams struct {
|
||||||
// The unique identifier for a mapfix.
|
// The unique identifier for a mapfix.
|
||||||
@@ -679,6 +596,89 @@ func decodeActionMapfixTriggerSubmitParams(args [1]string, argsEscaped bool, r *
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionMapfixTriggerSubmitUncheckedParams is parameters of actionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
type ActionMapfixTriggerSubmitUncheckedParams struct {
|
||||||
|
// The unique identifier for a mapfix.
|
||||||
|
MapfixID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackActionMapfixTriggerSubmitUncheckedParams(packed middleware.Parameters) (params ActionMapfixTriggerSubmitUncheckedParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.MapfixID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeActionMapfixTriggerSubmitUncheckedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixTriggerSubmitUncheckedParams, _ error) {
|
||||||
|
// Decode path: MapfixID.
|
||||||
|
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: "MapfixID",
|
||||||
|
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.MapfixID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.MapfixID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerUploadParams is parameters of actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUploadParams is parameters of actionMapfixTriggerUpload operation.
|
||||||
type ActionMapfixTriggerUploadParams struct {
|
type ActionMapfixTriggerUploadParams struct {
|
||||||
// The unique identifier for a mapfix.
|
// The unique identifier for a mapfix.
|
||||||
@@ -1011,89 +1011,6 @@ func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionBypassSubmitParams is parameters of actionSubmissionBypassSubmit operation.
|
|
||||||
type ActionSubmissionBypassSubmitParams struct {
|
|
||||||
// The unique identifier for a submission.
|
|
||||||
SubmissionID int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackActionSubmissionBypassSubmitParams(packed middleware.Parameters) (params ActionSubmissionBypassSubmitParams) {
|
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "SubmissionID",
|
|
||||||
In: "path",
|
|
||||||
}
|
|
||||||
params.SubmissionID = packed[key].(int64)
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeActionSubmissionBypassSubmitParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionBypassSubmitParams, _ 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
|
|
||||||
}
|
|
||||||
if err := func() error {
|
|
||||||
if err := (validate.Int{
|
|
||||||
MinSet: true,
|
|
||||||
Min: 0,
|
|
||||||
MaxSet: false,
|
|
||||||
Max: 0,
|
|
||||||
MinExclusive: false,
|
|
||||||
MaxExclusive: false,
|
|
||||||
MultipleOfSet: false,
|
|
||||||
MultipleOf: 0,
|
|
||||||
}).Validate(int64(params.SubmissionID)); err != nil {
|
|
||||||
return errors.Wrap(err, "int")
|
|
||||||
}
|
|
||||||
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.
|
||||||
@@ -1592,6 +1509,89 @@ func decodeActionSubmissionTriggerSubmitParams(args [1]string, argsEscaped bool,
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionTriggerSubmitUncheckedParams is parameters of actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
type ActionSubmissionTriggerSubmitUncheckedParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackActionSubmissionTriggerSubmitUncheckedParams(packed middleware.Parameters) (params ActionSubmissionTriggerSubmitUncheckedParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionTriggerSubmitUncheckedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionTriggerSubmitUncheckedParams, _ 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
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.SubmissionID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUploadParams is parameters of actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUploadParams is parameters of actionSubmissionTriggerUpload operation.
|
||||||
type ActionSubmissionTriggerUploadParams struct {
|
type ActionSubmissionTriggerUploadParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
@@ -2256,6 +2256,88 @@ func decodeGetMapParams(args [1]string, argsEscaped bool, r *http.Request) (para
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMapAssetLocationParams is parameters of getMapAssetLocation operation.
|
||||||
|
type GetMapAssetLocationParams struct {
|
||||||
|
MapID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackGetMapAssetLocationParams(packed middleware.Parameters) (params GetMapAssetLocationParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "MapID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.MapID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeGetMapAssetLocationParams(args [1]string, argsEscaped bool, r *http.Request) (params GetMapAssetLocationParams, _ error) {
|
||||||
|
// Decode path: MapID.
|
||||||
|
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: "MapID",
|
||||||
|
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.MapID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.MapID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "MapID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMapfixParams is parameters of getMapfix operation.
|
// GetMapfixParams is parameters of getMapfix operation.
|
||||||
type GetMapfixParams struct {
|
type GetMapfixParams struct {
|
||||||
// The unique identifier for a mapfix.
|
// The unique identifier for a mapfix.
|
||||||
@@ -2879,16 +2961,25 @@ func decodeListMapfixAuditEventsParams(args [1]string, argsEscaped bool, r *http
|
|||||||
|
|
||||||
// ListMapfixesParams is parameters of listMapfixes operation.
|
// ListMapfixesParams is parameters of listMapfixes operation.
|
||||||
type ListMapfixesParams struct {
|
type ListMapfixesParams struct {
|
||||||
Page int32
|
Page int32
|
||||||
Limit int32
|
Limit int32
|
||||||
DisplayName OptString
|
DisplayName OptString
|
||||||
Creator OptString
|
Creator OptString
|
||||||
GameID OptInt32
|
// Game ID: * `1` - Bhop * `2` - Surf * `5` - FlyTrials.
|
||||||
|
GameID OptInt32
|
||||||
|
// Sort order: * `0` - Disabled * `1` - DisplayNameAscending * `2` - DisplayNameDescending * `3` -
|
||||||
|
// DateAscending * `4` - DateDescending.
|
||||||
Sort OptInt32
|
Sort OptInt32
|
||||||
Submitter OptInt64
|
Submitter OptInt64
|
||||||
AssetID OptInt64
|
AssetID OptInt64
|
||||||
TargetAssetID OptInt64
|
TargetAssetID OptInt64
|
||||||
StatusID OptInt32
|
// // Phase: Creation * `0` - UnderConstruction * `1` - ChangesRequested
|
||||||
|
// // Phase: Review * `2` - Submitting * `3` - Submitted
|
||||||
|
// // Phase: Testing * `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
|
||||||
|
// * `5` - Validating * `6` - Validated * `7` - Uploading
|
||||||
|
// // Phase: Final MapfixStatus * `8` - Uploaded // uploaded to the group, but pending release * `9`
|
||||||
|
// - Rejected.
|
||||||
|
StatusID OptInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackListMapfixesParams(packed middleware.Parameters) (params ListMapfixesParams) {
|
func unpackListMapfixesParams(packed middleware.Parameters) (params ListMapfixesParams) {
|
||||||
@@ -3617,7 +3708,9 @@ type ListMapsParams struct {
|
|||||||
DisplayName OptString
|
DisplayName OptString
|
||||||
Creator OptString
|
Creator OptString
|
||||||
GameID OptInt32
|
GameID OptInt32
|
||||||
Sort OptInt32
|
// Sort order: * `0` - Disabled * `1` - DisplayNameAscending * `2` - DisplayNameDescending * `3` -
|
||||||
|
// DateAscending * `4` - DateDescending.
|
||||||
|
Sort OptInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackListMapsParams(packed middleware.Parameters) (params ListMapsParams) {
|
func unpackListMapsParams(packed middleware.Parameters) (params ListMapsParams) {
|
||||||
@@ -5117,16 +5210,25 @@ func decodeListSubmissionAuditEventsParams(args [1]string, argsEscaped bool, r *
|
|||||||
|
|
||||||
// ListSubmissionsParams is parameters of listSubmissions operation.
|
// ListSubmissionsParams is parameters of listSubmissions operation.
|
||||||
type ListSubmissionsParams struct {
|
type ListSubmissionsParams struct {
|
||||||
Page int32
|
Page int32
|
||||||
Limit int32
|
Limit int32
|
||||||
DisplayName OptString
|
DisplayName OptString
|
||||||
Creator OptString
|
Creator OptString
|
||||||
GameID OptInt32
|
// Game ID: * `1` - Bhop * `2` - Surf * `5` - FlyTrials.
|
||||||
|
GameID OptInt32
|
||||||
|
// Sort order: * `0` - Disabled * `1` - DisplayNameAscending * `2` - DisplayNameDescending * `3` -
|
||||||
|
// DateAscending * `4` - DateDescending.
|
||||||
Sort OptInt32
|
Sort OptInt32
|
||||||
Submitter OptInt64
|
Submitter OptInt64
|
||||||
AssetID OptInt64
|
AssetID OptInt64
|
||||||
UploadedAssetID OptInt64
|
UploadedAssetID OptInt64
|
||||||
StatusID OptInt32
|
// // Phase: Creation * `0` - UnderConstruction * `1` - ChangesRequested
|
||||||
|
// // Phase: Review * `2` - Submitting * `3` - Submitted
|
||||||
|
// // Phase: Testing * `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
|
||||||
|
// * `5` - Validating * `6` - Validated * `7` - Uploading * `8` - Uploaded // uploaded to the group,
|
||||||
|
// but pending release
|
||||||
|
// // Phase: Final SubmissionStatus * `9` - Rejected * `10` - Released.
|
||||||
|
StatusID OptInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackListSubmissionsParams(packed middleware.Parameters) (params ListSubmissionsParams) {
|
func unpackListSubmissionsParams(packed middleware.Parameters) (params ListSubmissionsParams) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
@@ -75,66 +76,6 @@ func decodeActionMapfixAcceptedResponse(resp *http.Response) (res *ActionMapfixA
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionMapfixBypassSubmitResponse(resp *http.Response) (res *ActionMapfixBypassSubmitNoContent, _ error) {
|
|
||||||
switch resp.StatusCode {
|
|
||||||
case 204:
|
|
||||||
// Code 204.
|
|
||||||
return &ActionMapfixBypassSubmitNoContent{}, 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
|
|
||||||
}
|
|
||||||
// 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 &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 decodeActionMapfixRejectResponse(resp *http.Response) (res *ActionMapfixRejectNoContent, _ error) {
|
func decodeActionMapfixRejectResponse(resp *http.Response) (res *ActionMapfixRejectNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -495,6 +436,66 @@ func decodeActionMapfixTriggerSubmitResponse(resp *http.Response) (res *ActionMa
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeActionMapfixTriggerSubmitUncheckedResponse(resp *http.Response) (res *ActionMapfixTriggerSubmitUncheckedNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &ActionMapfixTriggerSubmitUncheckedNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeActionMapfixTriggerUploadResponse(resp *http.Response) (res *ActionMapfixTriggerUploadNoContent, _ error) {
|
func decodeActionMapfixTriggerUploadResponse(resp *http.Response) (res *ActionMapfixTriggerUploadNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -735,66 +736,6 @@ func decodeActionSubmissionAcceptedResponse(resp *http.Response) (res *ActionSub
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionBypassSubmitResponse(resp *http.Response) (res *ActionSubmissionBypassSubmitNoContent, _ error) {
|
|
||||||
switch resp.StatusCode {
|
|
||||||
case 204:
|
|
||||||
// Code 204.
|
|
||||||
return &ActionSubmissionBypassSubmitNoContent{}, 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
|
|
||||||
}
|
|
||||||
// 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 &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:
|
||||||
@@ -1155,6 +1096,66 @@ func decodeActionSubmissionTriggerSubmitResponse(resp *http.Response) (res *Acti
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeActionSubmissionTriggerSubmitUncheckedResponse(resp *http.Response) (res *ActionSubmissionTriggerSubmitUncheckedNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &ActionSubmissionTriggerSubmitUncheckedNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeActionSubmissionTriggerUploadResponse(resp *http.Response) (res *ActionSubmissionTriggerUploadNoContent, _ error) {
|
func decodeActionSubmissionTriggerUploadResponse(resp *http.Response) (res *ActionSubmissionTriggerUploadNoContent, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 204:
|
case 204:
|
||||||
@@ -2181,6 +2182,82 @@ func decodeGetMapResponse(resp *http.Response) (res *Map, _ error) {
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeGetMapAssetLocationResponse(resp *http.Response) (res GetMapAssetLocationOK, _ 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 == "text/plain":
|
||||||
|
reader := resp.Body
|
||||||
|
b, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := GetMapAssetLocationOK{Data: bytes.NewReader(b)}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeGetMapfixResponse(resp *http.Response) (res *Mapfix, _ error) {
|
func decodeGetMapfixResponse(resp *http.Response) (res *Mapfix, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 200:
|
case 200:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-faster/errors"
|
"github.com/go-faster/errors"
|
||||||
@@ -20,13 +21,6 @@ func encodeActionMapfixAcceptedResponse(response *ActionMapfixAcceptedNoContent,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionMapfixBypassSubmitResponse(response *ActionMapfixBypassSubmitNoContent, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeActionMapfixRejectResponse(response *ActionMapfixRejectNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionMapfixRejectResponse(response *ActionMapfixRejectNoContent, 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))
|
||||||
@@ -69,6 +63,13 @@ func encodeActionMapfixTriggerSubmitResponse(response *ActionMapfixTriggerSubmit
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeActionMapfixTriggerSubmitUncheckedResponse(response *ActionMapfixTriggerSubmitUncheckedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeActionMapfixTriggerUploadResponse(response *ActionMapfixTriggerUploadNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionMapfixTriggerUploadResponse(response *ActionMapfixTriggerUploadNoContent, 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))
|
||||||
@@ -97,13 +98,6 @@ func encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionBypassSubmitResponse(response *ActionSubmissionBypassSubmitNoContent, 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))
|
||||||
@@ -146,6 +140,13 @@ func encodeActionSubmissionTriggerSubmitResponse(response *ActionSubmissionTrigg
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeActionSubmissionTriggerSubmitUncheckedResponse(response *ActionSubmissionTriggerSubmitUncheckedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionTriggerUploadResponse(response *ActionSubmissionTriggerUploadNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionSubmissionTriggerUploadResponse(response *ActionSubmissionTriggerUploadNoContent, 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))
|
||||||
@@ -279,6 +280,22 @@ func encodeGetMapResponse(response *Map, w http.ResponseWriter, span trace.Span)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeGetMapAssetLocationResponse(response GetMapAssetLocationOK, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
|
|
||||||
|
writer := w
|
||||||
|
if closer, ok := response.Data.(io.Closer); ok {
|
||||||
|
defer closer.Close()
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(writer, response); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeGetMapfixResponse(response *Mapfix, w http.ResponseWriter, span trace.Span) error {
|
func encodeGetMapfixResponse(response *Mapfix, 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(200)
|
w.WriteHeader(200)
|
||||||
|
|||||||
@@ -250,28 +250,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'b': // Prefix: "bypass-submit"
|
|
||||||
|
|
||||||
if l := len("bypass-submit"); len(elem) >= l && elem[0:l] == "bypass-submit" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleActionMapfixBypassSubmitRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'r': // Prefix: "re"
|
case 'r': // Prefix: "re"
|
||||||
|
|
||||||
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
||||||
@@ -475,7 +453,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "POST":
|
case "POST":
|
||||||
s.handleActionMapfixTriggerSubmitRequest([1]string{
|
s.handleActionMapfixTriggerSubmitRequest([1]string{
|
||||||
@@ -487,6 +464,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '-': // Prefix: "-unchecked"
|
||||||
|
|
||||||
|
if l := len("-unchecked"); len(elem) >= l && elem[0:l] == "-unchecked" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleActionMapfixTriggerSubmitUncheckedRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case 'u': // Prefix: "upload"
|
case 'u': // Prefix: "upload"
|
||||||
|
|
||||||
@@ -570,16 +571,15 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Param: "MapID"
|
// Param: "MapID"
|
||||||
// Leaf parameter, slashes are prohibited
|
// Match until "/"
|
||||||
idx := strings.IndexByte(elem, '/')
|
idx := strings.IndexByte(elem, '/')
|
||||||
if idx >= 0 {
|
if idx < 0 {
|
||||||
break
|
idx = len(elem)
|
||||||
}
|
}
|
||||||
args[0] = elem
|
args[0] = elem[:idx]
|
||||||
elem = ""
|
elem = elem[idx:]
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "GET":
|
case "GET":
|
||||||
s.handleGetMapRequest([1]string{
|
s.handleGetMapRequest([1]string{
|
||||||
@@ -591,6 +591,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '/': // Prefix: "/location"
|
||||||
|
|
||||||
|
if l := len("/location"); len(elem) >= l && elem[0:l] == "/location" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "GET":
|
||||||
|
s.handleGetMapAssetLocationRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "GET")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1068,28 +1092,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'b': // Prefix: "bypass-submit"
|
|
||||||
|
|
||||||
if l := len("bypass-submit"); len(elem) >= l && elem[0:l] == "bypass-submit" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
|
||||||
case "POST":
|
|
||||||
s.handleActionSubmissionBypassSubmitRequest([1]string{
|
|
||||||
args[0],
|
|
||||||
}, elemIsEscaped, w, r)
|
|
||||||
default:
|
|
||||||
s.notAllowed(w, r, "POST")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'r': // Prefix: "re"
|
case 'r': // Prefix: "re"
|
||||||
|
|
||||||
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
||||||
@@ -1293,7 +1295,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "POST":
|
case "POST":
|
||||||
s.handleActionSubmissionTriggerSubmitRequest([1]string{
|
s.handleActionSubmissionTriggerSubmitRequest([1]string{
|
||||||
@@ -1305,6 +1306,30 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '-': // Prefix: "-unchecked"
|
||||||
|
|
||||||
|
if l := len("-unchecked"); len(elem) >= l && elem[0:l] == "-unchecked" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleActionSubmissionTriggerSubmitUncheckedRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case 'u': // Prefix: "upload"
|
case 'u': // Prefix: "upload"
|
||||||
|
|
||||||
@@ -1665,30 +1690,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'b': // Prefix: "bypass-submit"
|
|
||||||
|
|
||||||
if l := len("bypass-submit"); len(elem) >= l && elem[0:l] == "bypass-submit" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
|
||||||
case "POST":
|
|
||||||
r.name = ActionMapfixBypassSubmitOperation
|
|
||||||
r.summary = "Role Reviewer changes status from ChangesRequested -> Submitted"
|
|
||||||
r.operationID = "actionMapfixBypassSubmit"
|
|
||||||
r.pathPattern = "/mapfixes/{MapfixID}/status/bypass-submit"
|
|
||||||
r.args = args
|
|
||||||
r.count = 1
|
|
||||||
return r, true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'r': // Prefix: "re"
|
case 'r': // Prefix: "re"
|
||||||
|
|
||||||
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
||||||
@@ -1906,7 +1907,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
switch method {
|
||||||
case "POST":
|
case "POST":
|
||||||
r.name = ActionMapfixTriggerSubmitOperation
|
r.name = ActionMapfixTriggerSubmitOperation
|
||||||
@@ -1920,6 +1920,32 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '-': // Prefix: "-unchecked"
|
||||||
|
|
||||||
|
if l := len("-unchecked"); len(elem) >= l && elem[0:l] == "-unchecked" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = ActionMapfixTriggerSubmitUncheckedOperation
|
||||||
|
r.summary = "Role Reviewer changes status from ChangesRequested -> Submitting"
|
||||||
|
r.operationID = "actionMapfixTriggerSubmitUnchecked"
|
||||||
|
r.pathPattern = "/mapfixes/{MapfixID}/status/trigger-submit-unchecked"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case 'u': // Prefix: "upload"
|
case 'u': // Prefix: "upload"
|
||||||
|
|
||||||
@@ -2011,16 +2037,15 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Param: "MapID"
|
// Param: "MapID"
|
||||||
// Leaf parameter, slashes are prohibited
|
// Match until "/"
|
||||||
idx := strings.IndexByte(elem, '/')
|
idx := strings.IndexByte(elem, '/')
|
||||||
if idx >= 0 {
|
if idx < 0 {
|
||||||
break
|
idx = len(elem)
|
||||||
}
|
}
|
||||||
args[0] = elem
|
args[0] = elem[:idx]
|
||||||
elem = ""
|
elem = elem[idx:]
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
switch method {
|
||||||
case "GET":
|
case "GET":
|
||||||
r.name = GetMapOperation
|
r.name = GetMapOperation
|
||||||
@@ -2034,6 +2059,32 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '/': // Prefix: "/location"
|
||||||
|
|
||||||
|
if l := len("/location"); len(elem) >= l && elem[0:l] == "/location" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "GET":
|
||||||
|
r.name = GetMapAssetLocationOperation
|
||||||
|
r.summary = "Get location of asset"
|
||||||
|
r.operationID = "getMapAssetLocation"
|
||||||
|
r.pathPattern = "/maps/{MapID}/location"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2593,30 +2644,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
case 'b': // Prefix: "bypass-submit"
|
|
||||||
|
|
||||||
if l := len("bypass-submit"); len(elem) >= l && elem[0:l] == "bypass-submit" {
|
|
||||||
elem = elem[l:]
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(elem) == 0 {
|
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
|
||||||
case "POST":
|
|
||||||
r.name = ActionSubmissionBypassSubmitOperation
|
|
||||||
r.summary = "Role Reviewer changes status from ChangesRequested -> Submitted"
|
|
||||||
r.operationID = "actionSubmissionBypassSubmit"
|
|
||||||
r.pathPattern = "/submissions/{SubmissionID}/status/bypass-submit"
|
|
||||||
r.args = args
|
|
||||||
r.count = 1
|
|
||||||
return r, true
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'r': // Prefix: "re"
|
case 'r': // Prefix: "re"
|
||||||
|
|
||||||
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
if l := len("re"); len(elem) >= l && elem[0:l] == "re" {
|
||||||
@@ -2834,7 +2861,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(elem) == 0 {
|
if len(elem) == 0 {
|
||||||
// Leaf node.
|
|
||||||
switch method {
|
switch method {
|
||||||
case "POST":
|
case "POST":
|
||||||
r.name = ActionSubmissionTriggerSubmitOperation
|
r.name = ActionSubmissionTriggerSubmitOperation
|
||||||
@@ -2848,6 +2874,32 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch elem[0] {
|
||||||
|
case '-': // Prefix: "-unchecked"
|
||||||
|
|
||||||
|
if l := len("-unchecked"); len(elem) >= l && elem[0:l] == "-unchecked" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = ActionSubmissionTriggerSubmitUncheckedOperation
|
||||||
|
r.summary = "Role Reviewer changes status from ChangesRequested -> Submitting"
|
||||||
|
r.operationID = "actionSubmissionTriggerSubmitUnchecked"
|
||||||
|
r.pathPattern = "/submissions/{SubmissionID}/status/trigger-submit-unchecked"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case 'u': // Prefix: "upload"
|
case 'u': // Prefix: "upload"
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ func (s *ErrorStatusCode) Error() string {
|
|||||||
// ActionMapfixAcceptedNoContent is response for ActionMapfixAccepted operation.
|
// ActionMapfixAcceptedNoContent is response for ActionMapfixAccepted operation.
|
||||||
type ActionMapfixAcceptedNoContent struct{}
|
type ActionMapfixAcceptedNoContent struct{}
|
||||||
|
|
||||||
// ActionMapfixBypassSubmitNoContent is response for ActionMapfixBypassSubmit operation.
|
|
||||||
type ActionMapfixBypassSubmitNoContent struct{}
|
|
||||||
|
|
||||||
// ActionMapfixRejectNoContent is response for ActionMapfixReject operation.
|
// ActionMapfixRejectNoContent is response for ActionMapfixReject operation.
|
||||||
type ActionMapfixRejectNoContent struct{}
|
type ActionMapfixRejectNoContent struct{}
|
||||||
|
|
||||||
@@ -38,6 +35,9 @@ type ActionMapfixRevokeNoContent struct{}
|
|||||||
// ActionMapfixTriggerSubmitNoContent is response for ActionMapfixTriggerSubmit operation.
|
// ActionMapfixTriggerSubmitNoContent is response for ActionMapfixTriggerSubmit operation.
|
||||||
type ActionMapfixTriggerSubmitNoContent struct{}
|
type ActionMapfixTriggerSubmitNoContent struct{}
|
||||||
|
|
||||||
|
// ActionMapfixTriggerSubmitUncheckedNoContent is response for ActionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
type ActionMapfixTriggerSubmitUncheckedNoContent struct{}
|
||||||
|
|
||||||
// ActionMapfixTriggerUploadNoContent is response for ActionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUploadNoContent is response for ActionMapfixTriggerUpload operation.
|
||||||
type ActionMapfixTriggerUploadNoContent struct{}
|
type ActionMapfixTriggerUploadNoContent struct{}
|
||||||
|
|
||||||
@@ -50,9 +50,6 @@ type ActionMapfixValidatedNoContent struct{}
|
|||||||
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
||||||
type ActionSubmissionAcceptedNoContent struct{}
|
type ActionSubmissionAcceptedNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionBypassSubmitNoContent is response for ActionSubmissionBypassSubmit operation.
|
|
||||||
type ActionSubmissionBypassSubmitNoContent struct{}
|
|
||||||
|
|
||||||
// ActionSubmissionRejectNoContent is response for ActionSubmissionReject operation.
|
// ActionSubmissionRejectNoContent is response for ActionSubmissionReject operation.
|
||||||
type ActionSubmissionRejectNoContent struct{}
|
type ActionSubmissionRejectNoContent struct{}
|
||||||
|
|
||||||
@@ -71,6 +68,9 @@ type ActionSubmissionRevokeNoContent struct{}
|
|||||||
// ActionSubmissionTriggerSubmitNoContent is response for ActionSubmissionTriggerSubmit operation.
|
// ActionSubmissionTriggerSubmitNoContent is response for ActionSubmissionTriggerSubmit operation.
|
||||||
type ActionSubmissionTriggerSubmitNoContent struct{}
|
type ActionSubmissionTriggerSubmitNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionTriggerSubmitUncheckedNoContent is response for ActionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
type ActionSubmissionTriggerSubmitUncheckedNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUploadNoContent is response for ActionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUploadNoContent is response for ActionSubmissionTriggerUpload operation.
|
||||||
type ActionSubmissionTriggerUploadNoContent struct{}
|
type ActionSubmissionTriggerUploadNoContent struct{}
|
||||||
|
|
||||||
@@ -304,6 +304,20 @@ func (s *ErrorStatusCode) SetResponse(val Error) {
|
|||||||
s.Response = val
|
s.Response = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetMapAssetLocationOK struct {
|
||||||
|
Data io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads data from the Data reader.
|
||||||
|
//
|
||||||
|
// Kept to satisfy the io.Reader interface.
|
||||||
|
func (s GetMapAssetLocationOK) Read(p []byte) (n int, err error) {
|
||||||
|
if s.Data == nil {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return s.Data.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/Map
|
// Ref: #/components/schemas/Map
|
||||||
type Map struct {
|
type Map struct {
|
||||||
ID int64 `json:"ID"`
|
ID int64 `json:"ID"`
|
||||||
|
|||||||
@@ -34,48 +34,49 @@ func findAuthorization(h http.Header, prefix string) (string, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var operationRolesCookieAuth = map[string][]string{
|
var operationRolesCookieAuth = map[string][]string{
|
||||||
ActionMapfixAcceptedOperation: []string{},
|
ActionMapfixAcceptedOperation: []string{},
|
||||||
ActionMapfixBypassSubmitOperation: []string{},
|
ActionMapfixRejectOperation: []string{},
|
||||||
ActionMapfixRejectOperation: []string{},
|
ActionMapfixRequestChangesOperation: []string{},
|
||||||
ActionMapfixRequestChangesOperation: []string{},
|
ActionMapfixResetSubmittingOperation: []string{},
|
||||||
ActionMapfixResetSubmittingOperation: []string{},
|
ActionMapfixRetryValidateOperation: []string{},
|
||||||
ActionMapfixRetryValidateOperation: []string{},
|
ActionMapfixRevokeOperation: []string{},
|
||||||
ActionMapfixRevokeOperation: []string{},
|
ActionMapfixTriggerSubmitOperation: []string{},
|
||||||
ActionMapfixTriggerSubmitOperation: []string{},
|
ActionMapfixTriggerSubmitUncheckedOperation: []string{},
|
||||||
ActionMapfixTriggerUploadOperation: []string{},
|
ActionMapfixTriggerUploadOperation: []string{},
|
||||||
ActionMapfixTriggerValidateOperation: []string{},
|
ActionMapfixTriggerValidateOperation: []string{},
|
||||||
ActionMapfixValidatedOperation: []string{},
|
ActionMapfixValidatedOperation: []string{},
|
||||||
ActionSubmissionAcceptedOperation: []string{},
|
ActionSubmissionAcceptedOperation: []string{},
|
||||||
ActionSubmissionBypassSubmitOperation: []string{},
|
ActionSubmissionRejectOperation: []string{},
|
||||||
ActionSubmissionRejectOperation: []string{},
|
ActionSubmissionRequestChangesOperation: []string{},
|
||||||
ActionSubmissionRequestChangesOperation: []string{},
|
ActionSubmissionResetSubmittingOperation: []string{},
|
||||||
ActionSubmissionResetSubmittingOperation: []string{},
|
ActionSubmissionRetryValidateOperation: []string{},
|
||||||
ActionSubmissionRetryValidateOperation: []string{},
|
ActionSubmissionRevokeOperation: []string{},
|
||||||
ActionSubmissionRevokeOperation: []string{},
|
ActionSubmissionTriggerSubmitOperation: []string{},
|
||||||
ActionSubmissionTriggerSubmitOperation: []string{},
|
ActionSubmissionTriggerSubmitUncheckedOperation: []string{},
|
||||||
ActionSubmissionTriggerUploadOperation: []string{},
|
ActionSubmissionTriggerUploadOperation: []string{},
|
||||||
ActionSubmissionTriggerValidateOperation: []string{},
|
ActionSubmissionTriggerValidateOperation: []string{},
|
||||||
ActionSubmissionValidatedOperation: []string{},
|
ActionSubmissionValidatedOperation: []string{},
|
||||||
CreateMapfixOperation: []string{},
|
CreateMapfixOperation: []string{},
|
||||||
CreateMapfixAuditCommentOperation: []string{},
|
CreateMapfixAuditCommentOperation: []string{},
|
||||||
CreateScriptOperation: []string{},
|
CreateScriptOperation: []string{},
|
||||||
CreateScriptPolicyOperation: []string{},
|
CreateScriptPolicyOperation: []string{},
|
||||||
CreateSubmissionOperation: []string{},
|
CreateSubmissionOperation: []string{},
|
||||||
CreateSubmissionAdminOperation: []string{},
|
CreateSubmissionAdminOperation: []string{},
|
||||||
CreateSubmissionAuditCommentOperation: []string{},
|
CreateSubmissionAuditCommentOperation: []string{},
|
||||||
DeleteScriptOperation: []string{},
|
DeleteScriptOperation: []string{},
|
||||||
DeleteScriptPolicyOperation: []string{},
|
DeleteScriptPolicyOperation: []string{},
|
||||||
GetOperationOperation: []string{},
|
GetMapAssetLocationOperation: []string{},
|
||||||
ReleaseSubmissionsOperation: []string{},
|
GetOperationOperation: []string{},
|
||||||
SessionRolesOperation: []string{},
|
ReleaseSubmissionsOperation: []string{},
|
||||||
SessionUserOperation: []string{},
|
SessionRolesOperation: []string{},
|
||||||
SessionValidateOperation: []string{},
|
SessionUserOperation: []string{},
|
||||||
SetMapfixCompletedOperation: []string{},
|
SessionValidateOperation: []string{},
|
||||||
SetSubmissionCompletedOperation: []string{},
|
SetMapfixCompletedOperation: []string{},
|
||||||
UpdateMapfixModelOperation: []string{},
|
SetSubmissionCompletedOperation: []string{},
|
||||||
UpdateScriptOperation: []string{},
|
UpdateMapfixModelOperation: []string{},
|
||||||
UpdateScriptPolicyOperation: []string{},
|
UpdateScriptOperation: []string{},
|
||||||
UpdateSubmissionModelOperation: []string{},
|
UpdateScriptPolicyOperation: []string{},
|
||||||
|
UpdateSubmissionModelOperation: []string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) securityCookieAuth(ctx context.Context, operationName OperationName, req *http.Request) (context.Context, bool, error) {
|
func (s *Server) securityCookieAuth(ctx context.Context, operationName OperationName, req *http.Request) (context.Context, bool, error) {
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/reset-validating
|
// POST /mapfixes/{MapfixID}/status/reset-validating
|
||||||
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
|
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
|
||||||
// ActionMapfixBypassSubmit implements actionMapfixBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/bypass-submit
|
|
||||||
ActionMapfixBypassSubmit(ctx context.Context, params ActionMapfixBypassSubmitParams) error
|
|
||||||
// ActionMapfixReject implements actionMapfixReject operation.
|
// ActionMapfixReject implements actionMapfixReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -57,6 +51,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
||||||
ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error
|
ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error
|
||||||
|
// ActionMapfixTriggerSubmitUnchecked implements actionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-submit-unchecked
|
||||||
|
ActionMapfixTriggerSubmitUnchecked(ctx context.Context, params ActionMapfixTriggerSubmitUncheckedParams) error
|
||||||
// ActionMapfixTriggerUpload implements actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUpload implements actionMapfixTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -81,12 +81,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/reset-validating
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
// ActionSubmissionBypassSubmit implements actionSubmissionBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/bypass-submit
|
|
||||||
ActionSubmissionBypassSubmit(ctx context.Context, params ActionSubmissionBypassSubmitParams) error
|
|
||||||
// ActionSubmissionReject implements actionSubmissionReject operation.
|
// ActionSubmissionReject implements actionSubmissionReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -124,6 +118,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-submit
|
// POST /submissions/{SubmissionID}/status/trigger-submit
|
||||||
ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error
|
ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error
|
||||||
|
// ActionSubmissionTriggerSubmitUnchecked implements actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-submit-unchecked
|
||||||
|
ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params ActionSubmissionTriggerSubmitUncheckedParams) error
|
||||||
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -202,6 +202,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// GET /maps/{MapID}
|
// GET /maps/{MapID}
|
||||||
GetMap(ctx context.Context, params GetMapParams) (*Map, error)
|
GetMap(ctx context.Context, params GetMapParams) (*Map, error)
|
||||||
|
// GetMapAssetLocation implements getMapAssetLocation operation.
|
||||||
|
//
|
||||||
|
// Get location of asset.
|
||||||
|
//
|
||||||
|
// GET /maps/{MapID}/location
|
||||||
|
GetMapAssetLocation(ctx context.Context, params GetMapAssetLocationParams) (GetMapAssetLocationOK, error)
|
||||||
// GetMapfix implements getMapfix operation.
|
// GetMapfix implements getMapfix operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
|
|||||||
@@ -22,15 +22,6 @@ func (UnimplementedHandler) ActionMapfixAccepted(ctx context.Context, params Act
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixBypassSubmit implements actionMapfixBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/bypass-submit
|
|
||||||
func (UnimplementedHandler) ActionMapfixBypassSubmit(ctx context.Context, params ActionMapfixBypassSubmitParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixReject implements actionMapfixReject operation.
|
// ActionMapfixReject implements actionMapfixReject operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from Submitted -> Rejected.
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
@@ -86,6 +77,15 @@ func (UnimplementedHandler) ActionMapfixTriggerSubmit(ctx context.Context, param
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionMapfixTriggerSubmitUnchecked implements actionMapfixTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-submit-unchecked
|
||||||
|
func (UnimplementedHandler) ActionMapfixTriggerSubmitUnchecked(ctx context.Context, params ActionMapfixTriggerSubmitUncheckedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerUpload implements actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUpload implements actionMapfixTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -122,15 +122,6 @@ func (UnimplementedHandler) ActionSubmissionAccepted(ctx context.Context, params
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionBypassSubmit implements actionSubmissionBypassSubmit operation.
|
|
||||||
//
|
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/bypass-submit
|
|
||||||
func (UnimplementedHandler) ActionSubmissionBypassSubmit(ctx context.Context, params ActionSubmissionBypassSubmitParams) 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.
|
||||||
@@ -186,6 +177,15 @@ func (UnimplementedHandler) ActionSubmissionTriggerSubmit(ctx context.Context, p
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionTriggerSubmitUnchecked implements actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-submit-unchecked
|
||||||
|
func (UnimplementedHandler) ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params ActionSubmissionTriggerSubmitUncheckedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
|
||||||
//
|
//
|
||||||
// Role Admin changes status from Validated -> Uploading.
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
@@ -303,6 +303,15 @@ func (UnimplementedHandler) GetMap(ctx context.Context, params GetMapParams) (r
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMapAssetLocation implements getMapAssetLocation operation.
|
||||||
|
//
|
||||||
|
// Get location of asset.
|
||||||
|
//
|
||||||
|
// GET /maps/{MapID}/location
|
||||||
|
func (UnimplementedHandler) GetMapAssetLocation(ctx context.Context, params GetMapAssetLocationParams) (r GetMapAssetLocationOK, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// GetMapfix implements getMapfix operation.
|
// GetMapfix implements getMapfix operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"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"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/roblox"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service_internal"
|
"git.itzana.me/strafesnet/maps-service/pkg/service_internal"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
@@ -91,6 +92,12 @@ func NewServeCommand() *cli.Command {
|
|||||||
EnvVars: []string{"NATS_HOST"},
|
EnvVars: []string{"NATS_HOST"},
|
||||||
Value: "nats:4222",
|
Value: "nats:4222",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "rbx-api-key",
|
||||||
|
Usage: "API Key for downloading asset locations",
|
||||||
|
EnvVars: []string{"RBX_API_KEY"},
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,6 +135,10 @@ func serve(ctx *cli.Context) error {
|
|||||||
Nats: js,
|
Nats: js,
|
||||||
Maps: maps.NewMapsServiceClient(conn),
|
Maps: maps.NewMapsServiceClient(conn),
|
||||||
Users: users.NewUsersServiceClient(conn),
|
Users: users.NewUsersServiceClient(conn),
|
||||||
|
Roblox: roblox.Client{
|
||||||
|
HttpClient: http.DefaultClient,
|
||||||
|
ApiKey: ctx.String("rbx-api-key"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
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()))
|
||||||
|
|||||||
@@ -100,6 +100,18 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes
|
// POST /mapfixes
|
||||||
CreateMapfix(ctx context.Context, request *MapfixCreate) (*MapfixID, error)
|
CreateMapfix(ctx context.Context, request *MapfixCreate) (*MapfixID, error)
|
||||||
|
// CreateMapfixAuditCheckList invokes createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
CreateMapfixAuditCheckList(ctx context.Context, request CheckList, params CreateMapfixAuditCheckListParams) error
|
||||||
|
// CreateMapfixAuditError invokes createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error
|
||||||
// CreateScript invokes createScript operation.
|
// CreateScript invokes createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -118,6 +130,18 @@ type Invoker interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions
|
// POST /submissions
|
||||||
CreateSubmission(ctx context.Context, request *SubmissionCreate) (*SubmissionID, error)
|
CreateSubmission(ctx context.Context, request *SubmissionCreate) (*SubmissionID, error)
|
||||||
|
// CreateSubmissionAuditCheckList invokes createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
CreateSubmissionAuditCheckList(ctx context.Context, request CheckList, params CreateSubmissionAuditCheckListParams) error
|
||||||
|
// CreateSubmissionAuditError invokes createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error
|
||||||
// GetScript invokes getScript operation.
|
// GetScript invokes getScript operation.
|
||||||
//
|
//
|
||||||
// Get the specified script by ID.
|
// Get the specified script by ID.
|
||||||
@@ -266,24 +290,6 @@ func (c *Client) sendActionMapfixAccepted(ctx context.Context, params ActionMapf
|
|||||||
pathParts[2] = "/status/validator-failed"
|
pathParts[2] = "/status/validator-failed"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
stage = "EncodeQueryParams"
|
|
||||||
q := uri.NewQueryEncoder()
|
|
||||||
{
|
|
||||||
// Encode "ErrorMessage" parameter.
|
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
|
||||||
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
|
||||||
}); 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 {
|
||||||
@@ -375,24 +381,6 @@ func (c *Client) sendActionMapfixRequestChanges(ctx context.Context, params Acti
|
|||||||
pathParts[2] = "/status/validator-request-changes"
|
pathParts[2] = "/status/validator-request-changes"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
stage = "EncodeQueryParams"
|
|
||||||
q := uri.NewQueryEncoder()
|
|
||||||
{
|
|
||||||
// Encode "ErrorMessage" parameter.
|
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
|
||||||
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
|
||||||
}); 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 {
|
||||||
@@ -926,24 +914,6 @@ 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 "ErrorMessage" parameter.
|
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
|
||||||
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
|
||||||
}); 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 {
|
||||||
@@ -1035,24 +1005,6 @@ func (c *Client) sendActionSubmissionRequestChanges(ctx context.Context, params
|
|||||||
pathParts[2] = "/status/validator-request-changes"
|
pathParts[2] = "/status/validator-request-changes"
|
||||||
uri.AddPathParts(u, pathParts[:]...)
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
stage = "EncodeQueryParams"
|
|
||||||
q := uri.NewQueryEncoder()
|
|
||||||
{
|
|
||||||
// Encode "ErrorMessage" parameter.
|
|
||||||
cfg := uri.QueryParameterEncodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
|
||||||
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
|
||||||
}); 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 {
|
||||||
@@ -1501,6 +1453,209 @@ func (c *Client) sendCreateMapfix(ctx context.Context, request *MapfixCreate) (r
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditCheckList invokes createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
func (c *Client) CreateMapfixAuditCheckList(ctx context.Context, request CheckList, params CreateMapfixAuditCheckListParams) error {
|
||||||
|
_, err := c.sendCreateMapfixAuditCheckList(ctx, request, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendCreateMapfixAuditCheckList(ctx context.Context, request CheckList, params CreateMapfixAuditCheckListParams) (res *CreateMapfixAuditCheckListNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createMapfixAuditCheckList"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/checklist"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, CreateMapfixAuditCheckListOperation,
|
||||||
|
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] = "/mapfixes/"
|
||||||
|
{
|
||||||
|
// Encode "MapfixID" parameter.
|
||||||
|
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
||||||
|
Param: "MapfixID",
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
if err := func() error {
|
||||||
|
return e.EncodeValue(conv.Int64ToString(params.MapfixID))
|
||||||
|
}(); 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] = "/checklist"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeRequest"
|
||||||
|
r, err := ht.NewRequest(ctx, "POST", u)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "create request")
|
||||||
|
}
|
||||||
|
if err := encodeCreateMapfixAuditCheckListRequest(request, r); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode 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 := decodeCreateMapfixAuditCheckListResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditError invokes createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
func (c *Client) CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error {
|
||||||
|
_, err := c.sendCreateMapfixAuditError(ctx, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendCreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) (res *CreateMapfixAuditErrorNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createMapfixAuditError"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, CreateMapfixAuditErrorOperation,
|
||||||
|
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] = "/mapfixes/"
|
||||||
|
{
|
||||||
|
// Encode "MapfixID" parameter.
|
||||||
|
e := uri.NewPathEncoder(uri.PathEncoderConfig{
|
||||||
|
Param: "MapfixID",
|
||||||
|
Style: uri.PathStyleSimple,
|
||||||
|
Explode: false,
|
||||||
|
})
|
||||||
|
if err := func() error {
|
||||||
|
return e.EncodeValue(conv.Int64ToString(params.MapfixID))
|
||||||
|
}(); 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] = "/error"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeQueryParams"
|
||||||
|
q := uri.NewQueryEncoder()
|
||||||
|
{
|
||||||
|
// Encode "ErrorMessage" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Values().Encode()
|
||||||
|
|
||||||
|
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 := decodeCreateMapfixAuditErrorResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateScript invokes createScript operation.
|
// CreateScript invokes createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -1726,6 +1881,209 @@ func (c *Client) sendCreateSubmission(ctx context.Context, request *SubmissionCr
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditCheckList invokes createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
func (c *Client) CreateSubmissionAuditCheckList(ctx context.Context, request CheckList, params CreateSubmissionAuditCheckListParams) error {
|
||||||
|
_, err := c.sendCreateSubmissionAuditCheckList(ctx, request, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendCreateSubmissionAuditCheckList(ctx context.Context, request CheckList, params CreateSubmissionAuditCheckListParams) (res *CreateSubmissionAuditCheckListNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createSubmissionAuditCheckList"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/checklist"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, CreateSubmissionAuditCheckListOperation,
|
||||||
|
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] = "/checklist"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeRequest"
|
||||||
|
r, err := ht.NewRequest(ctx, "POST", u)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "create request")
|
||||||
|
}
|
||||||
|
if err := encodeCreateSubmissionAuditCheckListRequest(request, r); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode 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 := decodeCreateSubmissionAuditCheckListResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditError invokes createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
func (c *Client) CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error {
|
||||||
|
_, err := c.sendCreateSubmissionAuditError(ctx, params)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) sendCreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) (res *CreateSubmissionAuditErrorNoContent, err error) {
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createSubmissionAuditError"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, CreateSubmissionAuditErrorOperation,
|
||||||
|
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] = "/error"
|
||||||
|
uri.AddPathParts(u, pathParts[:]...)
|
||||||
|
|
||||||
|
stage = "EncodeQueryParams"
|
||||||
|
q := uri.NewQueryEncoder()
|
||||||
|
{
|
||||||
|
// Encode "ErrorMessage" parameter.
|
||||||
|
cfg := uri.QueryParameterEncodingConfig{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
|
||||||
|
return e.EncodeValue(conv.StringToString(params.ErrorMessage))
|
||||||
|
}); err != nil {
|
||||||
|
return res, errors.Wrap(err, "encode query")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.RawQuery = q.Values().Encode()
|
||||||
|
|
||||||
|
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 := decodeCreateSubmissionAuditErrorResponse(resp)
|
||||||
|
if err != nil {
|
||||||
|
return res, errors.Wrap(err, "decode response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetScript invokes getScript operation.
|
// GetScript invokes getScript operation.
|
||||||
//
|
//
|
||||||
// Get the specified script by ID.
|
// Get the specified script by ID.
|
||||||
|
|||||||
@@ -128,10 +128,6 @@ func (s *Server) handleActionMapfixAcceptedRequest(args [1]string, argsEscaped b
|
|||||||
Name: "MapfixID",
|
Name: "MapfixID",
|
||||||
In: "path",
|
In: "path",
|
||||||
}: params.MapfixID,
|
}: params.MapfixID,
|
||||||
{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}: params.ErrorMessage,
|
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -281,10 +277,6 @@ func (s *Server) handleActionMapfixRequestChangesRequest(args [1]string, argsEsc
|
|||||||
Name: "MapfixID",
|
Name: "MapfixID",
|
||||||
In: "path",
|
In: "path",
|
||||||
}: params.MapfixID,
|
}: params.MapfixID,
|
||||||
{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}: params.ErrorMessage,
|
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -1050,10 +1042,6 @@ func (s *Server) handleActionSubmissionAcceptedRequest(args [1]string, argsEscap
|
|||||||
Name: "SubmissionID",
|
Name: "SubmissionID",
|
||||||
In: "path",
|
In: "path",
|
||||||
}: params.SubmissionID,
|
}: params.SubmissionID,
|
||||||
{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}: params.ErrorMessage,
|
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -1203,10 +1191,6 @@ func (s *Server) handleActionSubmissionRequestChangesRequest(args [1]string, arg
|
|||||||
Name: "SubmissionID",
|
Name: "SubmissionID",
|
||||||
In: "path",
|
In: "path",
|
||||||
}: params.SubmissionID,
|
}: params.SubmissionID,
|
||||||
{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}: params.ErrorMessage,
|
|
||||||
},
|
},
|
||||||
Raw: r,
|
Raw: r,
|
||||||
}
|
}
|
||||||
@@ -1874,6 +1858,323 @@ func (s *Server) handleCreateMapfixRequest(args [0]string, argsEscaped bool, w h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleCreateMapfixAuditCheckListRequest handles createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
func (s *Server) handleCreateMapfixAuditCheckListRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
||||||
|
statusWriter := &codeRecorder{ResponseWriter: w}
|
||||||
|
w = statusWriter
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createMapfixAuditCheckList"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/checklist"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a span for this request.
|
||||||
|
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateMapfixAuditCheckListOperation,
|
||||||
|
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: CreateMapfixAuditCheckListOperation,
|
||||||
|
ID: "createMapfixAuditCheckList",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
params, err := decodeCreateMapfixAuditCheckListParams(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
|
||||||
|
}
|
||||||
|
request, close, err := s.decodeCreateMapfixAuditCheckListRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
err = &ogenerrors.DecodeRequestError{
|
||||||
|
OperationContext: opErrContext,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
defer recordError("DecodeRequest", err)
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := close(); err != nil {
|
||||||
|
recordError("CloseRequest", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var response *CreateMapfixAuditCheckListNoContent
|
||||||
|
if m := s.cfg.Middleware; m != nil {
|
||||||
|
mreq := middleware.Request{
|
||||||
|
Context: ctx,
|
||||||
|
OperationName: CreateMapfixAuditCheckListOperation,
|
||||||
|
OperationSummary: "Validator posts a checklist to the audit log",
|
||||||
|
OperationID: "createMapfixAuditCheckList",
|
||||||
|
Body: request,
|
||||||
|
Params: middleware.Parameters{
|
||||||
|
{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
}: params.MapfixID,
|
||||||
|
},
|
||||||
|
Raw: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Request = CheckList
|
||||||
|
Params = CreateMapfixAuditCheckListParams
|
||||||
|
Response = *CreateMapfixAuditCheckListNoContent
|
||||||
|
)
|
||||||
|
response, err = middleware.HookMiddleware[
|
||||||
|
Request,
|
||||||
|
Params,
|
||||||
|
Response,
|
||||||
|
](
|
||||||
|
m,
|
||||||
|
mreq,
|
||||||
|
unpackCreateMapfixAuditCheckListParams,
|
||||||
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
|
err = s.h.CreateMapfixAuditCheckList(ctx, request, params)
|
||||||
|
return response, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = s.h.CreateMapfixAuditCheckList(ctx, request, 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 := encodeCreateMapfixAuditCheckListResponse(response, w, span); err != nil {
|
||||||
|
defer recordError("EncodeResponse", err)
|
||||||
|
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleCreateMapfixAuditErrorRequest handles createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
func (s *Server) handleCreateMapfixAuditErrorRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
||||||
|
statusWriter := &codeRecorder{ResponseWriter: w}
|
||||||
|
w = statusWriter
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createMapfixAuditError"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a span for this request.
|
||||||
|
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateMapfixAuditErrorOperation,
|
||||||
|
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: CreateMapfixAuditErrorOperation,
|
||||||
|
ID: "createMapfixAuditError",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
params, err := decodeCreateMapfixAuditErrorParams(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 *CreateMapfixAuditErrorNoContent
|
||||||
|
if m := s.cfg.Middleware; m != nil {
|
||||||
|
mreq := middleware.Request{
|
||||||
|
Context: ctx,
|
||||||
|
OperationName: CreateMapfixAuditErrorOperation,
|
||||||
|
OperationSummary: "Validator posts an error to the audit log",
|
||||||
|
OperationID: "createMapfixAuditError",
|
||||||
|
Body: nil,
|
||||||
|
Params: middleware.Parameters{
|
||||||
|
{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
}: params.MapfixID,
|
||||||
|
{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
}: params.ErrorMessage,
|
||||||
|
},
|
||||||
|
Raw: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Request = struct{}
|
||||||
|
Params = CreateMapfixAuditErrorParams
|
||||||
|
Response = *CreateMapfixAuditErrorNoContent
|
||||||
|
)
|
||||||
|
response, err = middleware.HookMiddleware[
|
||||||
|
Request,
|
||||||
|
Params,
|
||||||
|
Response,
|
||||||
|
](
|
||||||
|
m,
|
||||||
|
mreq,
|
||||||
|
unpackCreateMapfixAuditErrorParams,
|
||||||
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
|
err = s.h.CreateMapfixAuditError(ctx, params)
|
||||||
|
return response, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = s.h.CreateMapfixAuditError(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 := encodeCreateMapfixAuditErrorResponse(response, w, span); err != nil {
|
||||||
|
defer recordError("EncodeResponse", err)
|
||||||
|
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handleCreateScriptRequest handles createScript operation.
|
// handleCreateScriptRequest handles createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -2321,6 +2622,323 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleCreateSubmissionAuditCheckListRequest handles createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
func (s *Server) handleCreateSubmissionAuditCheckListRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
||||||
|
statusWriter := &codeRecorder{ResponseWriter: w}
|
||||||
|
w = statusWriter
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createSubmissionAuditCheckList"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/checklist"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a span for this request.
|
||||||
|
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateSubmissionAuditCheckListOperation,
|
||||||
|
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: CreateSubmissionAuditCheckListOperation,
|
||||||
|
ID: "createSubmissionAuditCheckList",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
params, err := decodeCreateSubmissionAuditCheckListParams(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
|
||||||
|
}
|
||||||
|
request, close, err := s.decodeCreateSubmissionAuditCheckListRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
err = &ogenerrors.DecodeRequestError{
|
||||||
|
OperationContext: opErrContext,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
defer recordError("DecodeRequest", err)
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := close(); err != nil {
|
||||||
|
recordError("CloseRequest", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var response *CreateSubmissionAuditCheckListNoContent
|
||||||
|
if m := s.cfg.Middleware; m != nil {
|
||||||
|
mreq := middleware.Request{
|
||||||
|
Context: ctx,
|
||||||
|
OperationName: CreateSubmissionAuditCheckListOperation,
|
||||||
|
OperationSummary: "Validator posts a checklist to the audit log",
|
||||||
|
OperationID: "createSubmissionAuditCheckList",
|
||||||
|
Body: request,
|
||||||
|
Params: middleware.Parameters{
|
||||||
|
{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}: params.SubmissionID,
|
||||||
|
},
|
||||||
|
Raw: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Request = CheckList
|
||||||
|
Params = CreateSubmissionAuditCheckListParams
|
||||||
|
Response = *CreateSubmissionAuditCheckListNoContent
|
||||||
|
)
|
||||||
|
response, err = middleware.HookMiddleware[
|
||||||
|
Request,
|
||||||
|
Params,
|
||||||
|
Response,
|
||||||
|
](
|
||||||
|
m,
|
||||||
|
mreq,
|
||||||
|
unpackCreateSubmissionAuditCheckListParams,
|
||||||
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
|
err = s.h.CreateSubmissionAuditCheckList(ctx, request, params)
|
||||||
|
return response, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = s.h.CreateSubmissionAuditCheckList(ctx, request, 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 := encodeCreateSubmissionAuditCheckListResponse(response, w, span); err != nil {
|
||||||
|
defer recordError("EncodeResponse", err)
|
||||||
|
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleCreateSubmissionAuditErrorRequest handles createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
func (s *Server) handleCreateSubmissionAuditErrorRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) {
|
||||||
|
statusWriter := &codeRecorder{ResponseWriter: w}
|
||||||
|
w = statusWriter
|
||||||
|
otelAttrs := []attribute.KeyValue{
|
||||||
|
otelogen.OperationID("createSubmissionAuditError"),
|
||||||
|
semconv.HTTPRequestMethodKey.String("POST"),
|
||||||
|
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a span for this request.
|
||||||
|
ctx, span := s.cfg.Tracer.Start(r.Context(), CreateSubmissionAuditErrorOperation,
|
||||||
|
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: CreateSubmissionAuditErrorOperation,
|
||||||
|
ID: "createSubmissionAuditError",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
params, err := decodeCreateSubmissionAuditErrorParams(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 *CreateSubmissionAuditErrorNoContent
|
||||||
|
if m := s.cfg.Middleware; m != nil {
|
||||||
|
mreq := middleware.Request{
|
||||||
|
Context: ctx,
|
||||||
|
OperationName: CreateSubmissionAuditErrorOperation,
|
||||||
|
OperationSummary: "Validator posts an error to the audit log",
|
||||||
|
OperationID: "createSubmissionAuditError",
|
||||||
|
Body: nil,
|
||||||
|
Params: middleware.Parameters{
|
||||||
|
{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}: params.SubmissionID,
|
||||||
|
{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
}: params.ErrorMessage,
|
||||||
|
},
|
||||||
|
Raw: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
Request = struct{}
|
||||||
|
Params = CreateSubmissionAuditErrorParams
|
||||||
|
Response = *CreateSubmissionAuditErrorNoContent
|
||||||
|
)
|
||||||
|
response, err = middleware.HookMiddleware[
|
||||||
|
Request,
|
||||||
|
Params,
|
||||||
|
Response,
|
||||||
|
](
|
||||||
|
m,
|
||||||
|
mreq,
|
||||||
|
unpackCreateSubmissionAuditErrorParams,
|
||||||
|
func(ctx context.Context, request Request, params Params) (response Response, err error) {
|
||||||
|
err = s.h.CreateSubmissionAuditError(ctx, params)
|
||||||
|
return response, err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
err = s.h.CreateSubmissionAuditError(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 := encodeCreateSubmissionAuditErrorResponse(response, w, span); err != nil {
|
||||||
|
defer recordError("EncodeResponse", err)
|
||||||
|
if !errors.Is(err, ht.ErrInternalServerErrorResponse) {
|
||||||
|
s.cfg.ErrorHandler(ctx, w, r, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handleGetScriptRequest handles getScript operation.
|
// handleGetScriptRequest handles getScript operation.
|
||||||
//
|
//
|
||||||
// Get the specified script by ID.
|
// Get the specified script by ID.
|
||||||
|
|||||||
@@ -12,6 +12,186 @@ import (
|
|||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Encode implements json.Marshaler.
|
||||||
|
func (s *Check) Encode(e *jx.Encoder) {
|
||||||
|
e.ObjStart()
|
||||||
|
s.encodeFields(e)
|
||||||
|
e.ObjEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeFields encodes fields.
|
||||||
|
func (s *Check) encodeFields(e *jx.Encoder) {
|
||||||
|
{
|
||||||
|
e.FieldStart("Name")
|
||||||
|
e.Str(s.Name)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("Summary")
|
||||||
|
e.Str(s.Summary)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("Passed")
|
||||||
|
e.Bool(s.Passed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonFieldsNameOfCheck = [3]string{
|
||||||
|
0: "Name",
|
||||||
|
1: "Summary",
|
||||||
|
2: "Passed",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes Check from json.
|
||||||
|
func (s *Check) Decode(d *jx.Decoder) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("invalid: unable to decode Check to nil")
|
||||||
|
}
|
||||||
|
var requiredBitSet [1]uint8
|
||||||
|
|
||||||
|
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
||||||
|
switch string(k) {
|
||||||
|
case "Name":
|
||||||
|
requiredBitSet[0] |= 1 << 0
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.Name = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Name\"")
|
||||||
|
}
|
||||||
|
case "Summary":
|
||||||
|
requiredBitSet[0] |= 1 << 1
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.Summary = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Summary\"")
|
||||||
|
}
|
||||||
|
case "Passed":
|
||||||
|
requiredBitSet[0] |= 1 << 2
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Bool()
|
||||||
|
s.Passed = bool(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"Passed\"")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return d.Skip()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return errors.Wrap(err, "decode Check")
|
||||||
|
}
|
||||||
|
// 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(jsonFieldsNameOfCheck) {
|
||||||
|
name = jsonFieldsNameOfCheck[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 *Check) MarshalJSON() ([]byte, error) {
|
||||||
|
e := jx.Encoder{}
|
||||||
|
s.Encode(&e)
|
||||||
|
return e.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements stdjson.Unmarshaler.
|
||||||
|
func (s *Check) UnmarshalJSON(data []byte) error {
|
||||||
|
d := jx.DecodeBytes(data)
|
||||||
|
return s.Decode(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes CheckList as json.
|
||||||
|
func (s CheckList) Encode(e *jx.Encoder) {
|
||||||
|
unwrapped := []Check(s)
|
||||||
|
|
||||||
|
e.ArrStart()
|
||||||
|
for _, elem := range unwrapped {
|
||||||
|
elem.Encode(e)
|
||||||
|
}
|
||||||
|
e.ArrEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decodes CheckList from json.
|
||||||
|
func (s *CheckList) Decode(d *jx.Decoder) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("invalid: unable to decode CheckList to nil")
|
||||||
|
}
|
||||||
|
var unwrapped []Check
|
||||||
|
if err := func() error {
|
||||||
|
unwrapped = make([]Check, 0)
|
||||||
|
if err := d.Arr(func(d *jx.Decoder) error {
|
||||||
|
var elem Check
|
||||||
|
if err := elem.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
unwrapped = append(unwrapped, elem)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "alias")
|
||||||
|
}
|
||||||
|
*s = CheckList(unwrapped)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements stdjson.Marshaler.
|
||||||
|
func (s CheckList) MarshalJSON() ([]byte, error) {
|
||||||
|
e := jx.Encoder{}
|
||||||
|
s.Encode(&e)
|
||||||
|
return e.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements stdjson.Unmarshaler.
|
||||||
|
func (s *CheckList) UnmarshalJSON(data []byte) error {
|
||||||
|
d := jx.DecodeBytes(data)
|
||||||
|
return s.Decode(d)
|
||||||
|
}
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
// Encode implements json.Marshaler.
|
||||||
func (s *Error) Encode(e *jx.Encoder) {
|
func (s *Error) Encode(e *jx.Encoder) {
|
||||||
e.ObjStart()
|
e.ObjStart()
|
||||||
|
|||||||
@@ -18,9 +18,13 @@ const (
|
|||||||
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
|
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
|
||||||
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
CreateMapfixOperation OperationName = "CreateMapfix"
|
CreateMapfixOperation OperationName = "CreateMapfix"
|
||||||
|
CreateMapfixAuditCheckListOperation OperationName = "CreateMapfixAuditCheckList"
|
||||||
|
CreateMapfixAuditErrorOperation OperationName = "CreateMapfixAuditError"
|
||||||
CreateScriptOperation OperationName = "CreateScript"
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
CreateSubmissionOperation OperationName = "CreateSubmission"
|
CreateSubmissionOperation OperationName = "CreateSubmission"
|
||||||
|
CreateSubmissionAuditCheckListOperation OperationName = "CreateSubmissionAuditCheckList"
|
||||||
|
CreateSubmissionAuditErrorOperation OperationName = "CreateSubmissionAuditError"
|
||||||
GetScriptOperation OperationName = "GetScript"
|
GetScriptOperation OperationName = "GetScript"
|
||||||
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
ListScriptsOperation OperationName = "ListScripts"
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ import (
|
|||||||
// ActionMapfixAcceptedParams is parameters of actionMapfixAccepted operation.
|
// ActionMapfixAcceptedParams is parameters of actionMapfixAccepted operation.
|
||||||
type ActionMapfixAcceptedParams struct {
|
type ActionMapfixAcceptedParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
MapfixID int64
|
MapfixID int64
|
||||||
ErrorMessage string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionMapfixAcceptedParams(packed middleware.Parameters) (params ActionMapfixAcceptedParams) {
|
func unpackActionMapfixAcceptedParams(packed middleware.Parameters) (params ActionMapfixAcceptedParams) {
|
||||||
@@ -30,18 +29,10 @@ func unpackActionMapfixAcceptedParams(packed middleware.Parameters) (params Acti
|
|||||||
}
|
}
|
||||||
params.MapfixID = packed[key].(int64)
|
params.MapfixID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}
|
|
||||||
params.ErrorMessage = packed[key].(string)
|
|
||||||
}
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionMapfixAcceptedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixAcceptedParams, _ error) {
|
func decodeActionMapfixAcceptedParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixAcceptedParams, _ error) {
|
||||||
q := uri.NewQueryDecoder(r.URL.Query())
|
|
||||||
// Decode path: MapfixID.
|
// Decode path: MapfixID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
param := args[0]
|
param := args[0]
|
||||||
@@ -104,66 +95,13 @@ func decodeActionMapfixAcceptedParams(args [1]string, argsEscaped bool, r *http.
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: ErrorMessage.
|
|
||||||
if err := func() error {
|
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.HasParam(cfg); err == nil {
|
|
||||||
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
|
||||||
val, err := d.DecodeValue()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := conv.ToString(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
|
||||||
return errors.Wrap(err, "string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return params, &ogenerrors.DecodeParamError{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixRequestChangesParams is parameters of actionMapfixRequestChanges operation.
|
// ActionMapfixRequestChangesParams is parameters of actionMapfixRequestChanges operation.
|
||||||
type ActionMapfixRequestChangesParams struct {
|
type ActionMapfixRequestChangesParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
MapfixID int64
|
MapfixID int64
|
||||||
ErrorMessage string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionMapfixRequestChangesParams(packed middleware.Parameters) (params ActionMapfixRequestChangesParams) {
|
func unpackActionMapfixRequestChangesParams(packed middleware.Parameters) (params ActionMapfixRequestChangesParams) {
|
||||||
@@ -174,18 +112,10 @@ func unpackActionMapfixRequestChangesParams(packed middleware.Parameters) (param
|
|||||||
}
|
}
|
||||||
params.MapfixID = packed[key].(int64)
|
params.MapfixID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}
|
|
||||||
params.ErrorMessage = packed[key].(string)
|
|
||||||
}
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionMapfixRequestChangesParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixRequestChangesParams, _ error) {
|
func decodeActionMapfixRequestChangesParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionMapfixRequestChangesParams, _ error) {
|
||||||
q := uri.NewQueryDecoder(r.URL.Query())
|
|
||||||
// Decode path: MapfixID.
|
// Decode path: MapfixID.
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
param := args[0]
|
param := args[0]
|
||||||
@@ -248,58 +178,6 @@ func decodeActionMapfixRequestChangesParams(args [1]string, argsEscaped bool, r
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: ErrorMessage.
|
|
||||||
if err := func() error {
|
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.HasParam(cfg); err == nil {
|
|
||||||
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
|
||||||
val, err := d.DecodeValue()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := conv.ToString(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
|
||||||
return errors.Wrap(err, "string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return params, &ogenerrors.DecodeParamError{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,7 +821,6 @@ func decodeActionOperationFailedParams(args [1]string, argsEscaped bool, r *http
|
|||||||
type ActionSubmissionAcceptedParams struct {
|
type ActionSubmissionAcceptedParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ErrorMessage string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params ActionSubmissionAcceptedParams) {
|
func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params ActionSubmissionAcceptedParams) {
|
||||||
@@ -954,18 +831,10 @@ func unpackActionSubmissionAcceptedParams(packed middleware.Parameters) (params
|
|||||||
}
|
}
|
||||||
params.SubmissionID = packed[key].(int64)
|
params.SubmissionID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}
|
|
||||||
params.ErrorMessage = 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]
|
||||||
@@ -1028,58 +897,6 @@ func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: ErrorMessage.
|
|
||||||
if err := func() error {
|
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.HasParam(cfg); err == nil {
|
|
||||||
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
|
||||||
val, err := d.DecodeValue()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := conv.ToString(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
|
||||||
return errors.Wrap(err, "string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return params, &ogenerrors.DecodeParamError{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,7 +904,6 @@ func decodeActionSubmissionAcceptedParams(args [1]string, argsEscaped bool, r *h
|
|||||||
type ActionSubmissionRequestChangesParams struct {
|
type ActionSubmissionRequestChangesParams struct {
|
||||||
// The unique identifier for a submission.
|
// The unique identifier for a submission.
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ErrorMessage string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackActionSubmissionRequestChangesParams(packed middleware.Parameters) (params ActionSubmissionRequestChangesParams) {
|
func unpackActionSubmissionRequestChangesParams(packed middleware.Parameters) (params ActionSubmissionRequestChangesParams) {
|
||||||
@@ -1098,18 +914,10 @@ func unpackActionSubmissionRequestChangesParams(packed middleware.Parameters) (p
|
|||||||
}
|
}
|
||||||
params.SubmissionID = packed[key].(int64)
|
params.SubmissionID = packed[key].(int64)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
key := middleware.ParameterKey{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
}
|
|
||||||
params.ErrorMessage = packed[key].(string)
|
|
||||||
}
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeActionSubmissionRequestChangesParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionRequestChangesParams, _ error) {
|
func decodeActionSubmissionRequestChangesParams(args [1]string, argsEscaped bool, r *http.Request) (params ActionSubmissionRequestChangesParams, _ 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]
|
||||||
@@ -1172,58 +980,6 @@ func decodeActionSubmissionRequestChangesParams(args [1]string, argsEscaped bool
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decode query: ErrorMessage.
|
|
||||||
if err := func() error {
|
|
||||||
cfg := uri.QueryParameterDecodingConfig{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
Style: uri.QueryStyleForm,
|
|
||||||
Explode: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.HasParam(cfg); err == nil {
|
|
||||||
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
|
||||||
val, err := d.DecodeValue()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := conv.ToString(val)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
|
||||||
return errors.Wrap(err, "string")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return params, &ogenerrors.DecodeParamError{
|
|
||||||
Name: "ErrorMessage",
|
|
||||||
In: "query",
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1781,6 +1537,460 @@ func decodeActionSubmissionValidatedParams(args [1]string, argsEscaped bool, r *
|
|||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditCheckListParams is parameters of createMapfixAuditCheckList operation.
|
||||||
|
type CreateMapfixAuditCheckListParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
MapfixID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackCreateMapfixAuditCheckListParams(packed middleware.Parameters) (params CreateMapfixAuditCheckListParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.MapfixID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCreateMapfixAuditCheckListParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateMapfixAuditCheckListParams, _ error) {
|
||||||
|
// Decode path: MapfixID.
|
||||||
|
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: "MapfixID",
|
||||||
|
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.MapfixID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.MapfixID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditErrorParams is parameters of createMapfixAuditError operation.
|
||||||
|
type CreateMapfixAuditErrorParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
MapfixID int64
|
||||||
|
ErrorMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackCreateMapfixAuditErrorParams(packed middleware.Parameters) (params CreateMapfixAuditErrorParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.MapfixID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
params.ErrorMessage = packed[key].(string)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCreateMapfixAuditErrorParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateMapfixAuditErrorParams, _ error) {
|
||||||
|
q := uri.NewQueryDecoder(r.URL.Query())
|
||||||
|
// Decode path: MapfixID.
|
||||||
|
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: "MapfixID",
|
||||||
|
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.MapfixID = c
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.MapfixID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "MapfixID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Decode query: ErrorMessage.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToString(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditCheckListParams is parameters of createSubmissionAuditCheckList operation.
|
||||||
|
type CreateSubmissionAuditCheckListParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackCreateSubmissionAuditCheckListParams(packed middleware.Parameters) (params CreateSubmissionAuditCheckListParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCreateSubmissionAuditCheckListParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateSubmissionAuditCheckListParams, _ 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
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.SubmissionID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditErrorParams is parameters of createSubmissionAuditError operation.
|
||||||
|
type CreateSubmissionAuditErrorParams struct {
|
||||||
|
// The unique identifier for a submission.
|
||||||
|
SubmissionID int64
|
||||||
|
ErrorMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackCreateSubmissionAuditErrorParams(packed middleware.Parameters) (params CreateSubmissionAuditErrorParams) {
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
}
|
||||||
|
params.SubmissionID = packed[key].(int64)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
key := middleware.ParameterKey{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
}
|
||||||
|
params.ErrorMessage = packed[key].(string)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCreateSubmissionAuditErrorParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateSubmissionAuditErrorParams, _ error) {
|
||||||
|
q := uri.NewQueryDecoder(r.URL.Query())
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.Int{
|
||||||
|
MinSet: true,
|
||||||
|
Min: 0,
|
||||||
|
MaxSet: false,
|
||||||
|
Max: 0,
|
||||||
|
MinExclusive: false,
|
||||||
|
MaxExclusive: false,
|
||||||
|
MultipleOfSet: false,
|
||||||
|
MultipleOf: 0,
|
||||||
|
}).Validate(int64(params.SubmissionID)); err != nil {
|
||||||
|
return errors.Wrap(err, "int")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return validate.ErrFieldRequired
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "SubmissionID",
|
||||||
|
In: "path",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Decode query: ErrorMessage.
|
||||||
|
if err := func() error {
|
||||||
|
cfg := uri.QueryParameterDecodingConfig{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
Style: uri.QueryStyleForm,
|
||||||
|
Explode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.HasParam(cfg); err == nil {
|
||||||
|
if err := q.DecodeParam(cfg, func(d uri.Decoder) error {
|
||||||
|
val, err := d.DecodeValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := conv.ToString(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
params.ErrorMessage = 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.ErrorMessage)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return params, &ogenerrors.DecodeParamError{
|
||||||
|
Name: "ErrorMessage",
|
||||||
|
In: "query",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetScriptParams is parameters of getScript operation.
|
// GetScriptParams is parameters of getScript operation.
|
||||||
type GetScriptParams struct {
|
type GetScriptParams struct {
|
||||||
// The unique identifier for a script.
|
// The unique identifier for a script.
|
||||||
|
|||||||
@@ -85,6 +85,77 @@ func (s *Server) decodeCreateMapfixRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateMapfixAuditCheckListRequest(r *http.Request) (
|
||||||
|
req CheckList,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = errors.Join(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = errors.Join(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request CheckList
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) decodeCreateScriptRequest(r *http.Request) (
|
func (s *Server) decodeCreateScriptRequest(r *http.Request) (
|
||||||
req *ScriptCreate,
|
req *ScriptCreate,
|
||||||
close func() error,
|
close func() error,
|
||||||
@@ -297,3 +368,74 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
|
|||||||
return req, close, validate.InvalidContentType(ct)
|
return req, close, validate.InvalidContentType(ct)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateSubmissionAuditCheckListRequest(r *http.Request) (
|
||||||
|
req CheckList,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = errors.Join(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = errors.Join(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request CheckList
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,20 @@ func encodeCreateMapfixRequest(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeCreateMapfixAuditCheckListRequest(
|
||||||
|
req CheckList,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeCreateScriptRequest(
|
func encodeCreateScriptRequest(
|
||||||
req *ScriptCreate,
|
req *ScriptCreate,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
@@ -66,3 +80,17 @@ func encodeCreateSubmissionRequest(
|
|||||||
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeCreateSubmissionAuditCheckListRequest(
|
||||||
|
req CheckList,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -776,6 +776,126 @@ func decodeCreateMapfixResponse(resp *http.Response) (res *MapfixID, _ error) {
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeCreateMapfixAuditCheckListResponse(resp *http.Response) (res *CreateMapfixAuditCheckListNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &CreateMapfixAuditCheckListNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeCreateMapfixAuditErrorResponse(resp *http.Response) (res *CreateMapfixAuditErrorNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &CreateMapfixAuditErrorNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 *ScriptID, _ error) {
|
func decodeCreateScriptResponse(resp *http.Response) (res *ScriptID, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 201:
|
case 201:
|
||||||
@@ -1079,6 +1199,126 @@ func decodeCreateSubmissionResponse(resp *http.Response) (res *SubmissionID, _ e
|
|||||||
return res, errors.Wrap(defRes, "error")
|
return res, errors.Wrap(defRes, "error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeCreateSubmissionAuditCheckListResponse(resp *http.Response) (res *CreateSubmissionAuditCheckListNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &CreateSubmissionAuditCheckListNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeCreateSubmissionAuditErrorResponse(resp *http.Response) (res *CreateSubmissionAuditErrorNoContent, _ error) {
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case 204:
|
||||||
|
// Code 204.
|
||||||
|
return &CreateSubmissionAuditErrorNoContent{}, 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
|
||||||
|
}
|
||||||
|
// 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 &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 decodeGetScriptResponse(resp *http.Response) (res *Script, _ error) {
|
func decodeGetScriptResponse(resp *http.Response) (res *Script, _ error) {
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 200:
|
case 200:
|
||||||
|
|||||||
@@ -104,6 +104,20 @@ func encodeCreateMapfixResponse(response *MapfixID, w http.ResponseWriter, span
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeCreateMapfixAuditCheckListResponse(response *CreateMapfixAuditCheckListNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateMapfixAuditErrorResponse(response *CreateMapfixAuditErrorNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeCreateScriptResponse(response *ScriptID, w http.ResponseWriter, span trace.Span) error {
|
func encodeCreateScriptResponse(response *ScriptID, 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)
|
||||||
@@ -146,6 +160,20 @@ func encodeCreateSubmissionResponse(response *SubmissionID, w http.ResponseWrite
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeCreateSubmissionAuditCheckListResponse(response *CreateSubmissionAuditCheckListNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateSubmissionAuditErrorResponse(response *CreateSubmissionAuditErrorNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func encodeGetScriptResponse(response *Script, w http.ResponseWriter, span trace.Span) error {
|
func encodeGetScriptResponse(response *Script, 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(200)
|
w.WriteHeader(200)
|
||||||
|
|||||||
@@ -113,6 +113,50 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
|
case 'c': // Prefix: "checklist"
|
||||||
|
|
||||||
|
if l := len("checklist"); len(elem) >= l && elem[0:l] == "checklist" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleCreateMapfixAuditCheckListRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'e': // Prefix: "error"
|
||||||
|
|
||||||
|
if l := len("error"); len(elem) >= l && elem[0:l] == "error" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleCreateMapfixAuditErrorRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
case 's': // Prefix: "status/validator-"
|
case 's': // Prefix: "status/validator-"
|
||||||
|
|
||||||
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
@@ -464,6 +508,50 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
|
case 'c': // Prefix: "checklist"
|
||||||
|
|
||||||
|
if l := len("checklist"); len(elem) >= l && elem[0:l] == "checklist" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleCreateSubmissionAuditCheckListRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'e': // Prefix: "error"
|
||||||
|
|
||||||
|
if l := len("error"); len(elem) >= l && elem[0:l] == "error" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch r.Method {
|
||||||
|
case "POST":
|
||||||
|
s.handleCreateSubmissionAuditErrorRequest([1]string{
|
||||||
|
args[0],
|
||||||
|
}, elemIsEscaped, w, r)
|
||||||
|
default:
|
||||||
|
s.notAllowed(w, r, "POST")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
case 's': // Prefix: "status/validator-"
|
case 's': // Prefix: "status/validator-"
|
||||||
|
|
||||||
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
@@ -768,6 +856,54 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
|
case 'c': // Prefix: "checklist"
|
||||||
|
|
||||||
|
if l := len("checklist"); len(elem) >= l && elem[0:l] == "checklist" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = CreateMapfixAuditCheckListOperation
|
||||||
|
r.summary = "Validator posts a checklist to the audit log"
|
||||||
|
r.operationID = "createMapfixAuditCheckList"
|
||||||
|
r.pathPattern = "/mapfixes/{MapfixID}/checklist"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'e': // Prefix: "error"
|
||||||
|
|
||||||
|
if l := len("error"); len(elem) >= l && elem[0:l] == "error" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = CreateMapfixAuditErrorOperation
|
||||||
|
r.summary = "Validator posts an error to the audit log"
|
||||||
|
r.operationID = "createMapfixAuditError"
|
||||||
|
r.pathPattern = "/mapfixes/{MapfixID}/error"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 's': // Prefix: "status/validator-"
|
case 's': // Prefix: "status/validator-"
|
||||||
|
|
||||||
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
@@ -1159,6 +1295,54 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch elem[0] {
|
switch elem[0] {
|
||||||
|
case 'c': // Prefix: "checklist"
|
||||||
|
|
||||||
|
if l := len("checklist"); len(elem) >= l && elem[0:l] == "checklist" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = CreateSubmissionAuditCheckListOperation
|
||||||
|
r.summary = "Validator posts a checklist to the audit log"
|
||||||
|
r.operationID = "createSubmissionAuditCheckList"
|
||||||
|
r.pathPattern = "/submissions/{SubmissionID}/checklist"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'e': // Prefix: "error"
|
||||||
|
|
||||||
|
if l := len("error"); len(elem) >= l && elem[0:l] == "error" {
|
||||||
|
elem = elem[l:]
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(elem) == 0 {
|
||||||
|
// Leaf node.
|
||||||
|
switch method {
|
||||||
|
case "POST":
|
||||||
|
r.name = CreateSubmissionAuditErrorOperation
|
||||||
|
r.summary = "Validator posts an error to the audit log"
|
||||||
|
r.operationID = "createSubmissionAuditError"
|
||||||
|
r.pathPattern = "/submissions/{SubmissionID}/error"
|
||||||
|
r.args = args
|
||||||
|
r.count = 1
|
||||||
|
return r, true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 's': // Prefix: "status/validator-"
|
case 's': // Prefix: "status/validator-"
|
||||||
|
|
||||||
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
if l := len("status/validator-"); len(elem) >= l && elem[0:l] == "status/validator-" {
|
||||||
|
|||||||
@@ -43,6 +43,57 @@ type ActionSubmissionUploadedNoContent struct{}
|
|||||||
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
||||||
type ActionSubmissionValidatedNoContent struct{}
|
type ActionSubmissionValidatedNoContent struct{}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/Check
|
||||||
|
type Check struct {
|
||||||
|
Name string `json:"Name"`
|
||||||
|
Summary string `json:"Summary"`
|
||||||
|
Passed bool `json:"Passed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the value of Name.
|
||||||
|
func (s *Check) GetName() string {
|
||||||
|
return s.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSummary returns the value of Summary.
|
||||||
|
func (s *Check) GetSummary() string {
|
||||||
|
return s.Summary
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPassed returns the value of Passed.
|
||||||
|
func (s *Check) GetPassed() bool {
|
||||||
|
return s.Passed
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the value of Name.
|
||||||
|
func (s *Check) SetName(val string) {
|
||||||
|
s.Name = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSummary sets the value of Summary.
|
||||||
|
func (s *Check) SetSummary(val string) {
|
||||||
|
s.Summary = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPassed sets the value of Passed.
|
||||||
|
func (s *Check) SetPassed(val bool) {
|
||||||
|
s.Passed = val
|
||||||
|
}
|
||||||
|
|
||||||
|
type CheckList []Check
|
||||||
|
|
||||||
|
// CreateMapfixAuditCheckListNoContent is response for CreateMapfixAuditCheckList operation.
|
||||||
|
type CreateMapfixAuditCheckListNoContent struct{}
|
||||||
|
|
||||||
|
// CreateMapfixAuditErrorNoContent is response for CreateMapfixAuditError operation.
|
||||||
|
type CreateMapfixAuditErrorNoContent struct{}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditCheckListNoContent is response for CreateSubmissionAuditCheckList operation.
|
||||||
|
type CreateSubmissionAuditCheckListNoContent struct{}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditErrorNoContent is response for CreateSubmissionAuditError operation.
|
||||||
|
type CreateSubmissionAuditErrorNoContent struct{}
|
||||||
|
|
||||||
// Represents error object.
|
// Represents error object.
|
||||||
// Ref: #/components/schemas/Error
|
// Ref: #/components/schemas/Error
|
||||||
type Error struct {
|
type Error struct {
|
||||||
|
|||||||
@@ -80,6 +80,18 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes
|
// POST /mapfixes
|
||||||
CreateMapfix(ctx context.Context, req *MapfixCreate) (*MapfixID, error)
|
CreateMapfix(ctx context.Context, req *MapfixCreate) (*MapfixID, error)
|
||||||
|
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
CreateMapfixAuditCheckList(ctx context.Context, req CheckList, params CreateMapfixAuditCheckListParams) error
|
||||||
|
// CreateMapfixAuditError implements createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -98,6 +110,18 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions
|
// POST /submissions
|
||||||
CreateSubmission(ctx context.Context, req *SubmissionCreate) (*SubmissionID, error)
|
CreateSubmission(ctx context.Context, req *SubmissionCreate) (*SubmissionID, error)
|
||||||
|
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
CreateSubmissionAuditCheckList(ctx context.Context, req CheckList, params CreateSubmissionAuditCheckListParams) error
|
||||||
|
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error
|
||||||
// GetScript implements getScript operation.
|
// GetScript implements getScript operation.
|
||||||
//
|
//
|
||||||
// Get the specified script by ID.
|
// Get the specified script by ID.
|
||||||
|
|||||||
@@ -121,6 +121,24 @@ func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixCreate)
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
func (UnimplementedHandler) CreateMapfixAuditCheckList(ctx context.Context, req CheckList, params CreateMapfixAuditCheckListParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditError implements createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
func (UnimplementedHandler) CreateMapfixAuditError(ctx context.Context, params CreateMapfixAuditErrorParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -148,6 +166,24 @@ func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *Submissio
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Validator posts a checklist to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
func (UnimplementedHandler) CreateSubmissionAuditCheckList(ctx context.Context, req CheckList, params CreateSubmissionAuditCheckListParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Validator posts an error to the audit log.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
func (UnimplementedHandler) CreateSubmissionAuditError(ctx context.Context, params CreateSubmissionAuditErrorParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// GetScript implements getScript operation.
|
// GetScript implements getScript operation.
|
||||||
//
|
//
|
||||||
// Get the specified script by ID.
|
// Get the specified script by ID.
|
||||||
|
|||||||
@@ -3,11 +3,88 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-faster/errors"
|
"github.com/go-faster/errors"
|
||||||
|
|
||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Check) 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.Name)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Name",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: false,
|
||||||
|
MaxLength: 4096,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.Summary)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Summary",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CheckList) Validate() error {
|
||||||
|
alias := ([]Check)(s)
|
||||||
|
if alias == nil {
|
||||||
|
return errors.New("nil is invalid value")
|
||||||
|
}
|
||||||
|
var failures []validate.FieldError
|
||||||
|
for i, elem := range alias {
|
||||||
|
if err := func() error {
|
||||||
|
if err := elem.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: fmt.Sprintf("[%d]", i),
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Error) Validate() error {
|
func (s *Error) Validate() error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return validate.ErrNilPointer
|
return validate.ErrNilPointer
|
||||||
|
|||||||
@@ -48,6 +48,19 @@ type AuditEventDataError struct {
|
|||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Check struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Passed bool `json:"passed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validator map checks details
|
||||||
|
const AuditEventTypeCheckList AuditEventType = 7
|
||||||
|
|
||||||
|
type AuditEventDataCheckList struct {
|
||||||
|
CheckList []Check `json:"check_list"`
|
||||||
|
}
|
||||||
|
|
||||||
type AuditEvent struct {
|
type AuditEvent struct {
|
||||||
ID int64 `gorm:"primaryKey"`
|
ID int64 `gorm:"primaryKey"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ type CreateMapfixRequest struct {
|
|||||||
type CheckSubmissionRequest struct{
|
type CheckSubmissionRequest struct{
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID uint64
|
ModelID uint64
|
||||||
|
SkipChecks bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type CheckMapfixRequest struct{
|
type CheckMapfixRequest struct{
|
||||||
MapfixID int64
|
MapfixID int64
|
||||||
ModelID uint64
|
ModelID uint64
|
||||||
|
SkipChecks bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidateSubmissionRequest struct {
|
type ValidateSubmissionRequest struct {
|
||||||
|
|||||||
13
pkg/model/resource.go
Normal file
13
pkg/model/resource.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type ResourceType int32
|
||||||
|
const (
|
||||||
|
ResourceUnknown ResourceType = 0
|
||||||
|
ResourceMapfix ResourceType = 1
|
||||||
|
ResourceSubmission ResourceType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type Resource struct{
|
||||||
|
ID int64
|
||||||
|
Type ResourceType
|
||||||
|
}
|
||||||
@@ -23,13 +23,6 @@ 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
|
||||||
|
|||||||
72
pkg/roblox/asset_location.go
Normal file
72
pkg/roblox/asset_location.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Struct equivalent to Rust's AssetLocationInfo
|
||||||
|
type AssetLocationInfo struct {
|
||||||
|
Location string `json:"location"`
|
||||||
|
RequestId string `json:"requestId"`
|
||||||
|
IsHashDynamic bool `json:"IsHashDynamic"`
|
||||||
|
IsCopyrightProtected bool `json:"IsCopyrightProtected"`
|
||||||
|
IsArchived bool `json:"isArchived"`
|
||||||
|
AssetTypeId uint32 `json:"assetTypeId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input struct for getAssetLocation
|
||||||
|
type GetAssetLatestRequest struct {
|
||||||
|
AssetID uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom error type if needed
|
||||||
|
type GetError string
|
||||||
|
|
||||||
|
func (e GetError) Error() string { return string(e) }
|
||||||
|
|
||||||
|
// Example client with a Get method
|
||||||
|
type Client struct {
|
||||||
|
HttpClient *http.Client
|
||||||
|
ApiKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetAssetLocation(config GetAssetLatestRequest) (*AssetLocationInfo, error) {
|
||||||
|
rawURL := fmt.Sprintf("https://apis.roblox.com/asset-delivery-api/v1/assetId/%d", config.AssetID)
|
||||||
|
parsedURL, err := url.Parse(rawURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, GetError("ParseError: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", parsedURL.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, GetError("RequestCreationError: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("x-api-key", c.ApiKey)
|
||||||
|
|
||||||
|
resp, err := c.HttpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, GetError("ReqwestError: " + err.Error())
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, GetError(fmt.Sprintf("ResponseError: status code %d", resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, GetError("ReadBodyError: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var info AssetLocationInfo
|
||||||
|
if err := json.Unmarshal(body, &info); err != nil {
|
||||||
|
return nil, GetError("JSONError: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
||||||
@@ -10,85 +10,13 @@ import (
|
|||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateMapfixAuditComment implements createMapfixAuditComment operation.
|
func (svc *Service) ListAuditEvents(ctx context.Context, resource model.Resource, page model.Page) ([]api.AuditEvent, error){
|
||||||
//
|
|
||||||
// Post a comment to the audit log
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/comment
|
|
||||||
func (svc *Service) CreateMapfixAuditComment(ctx context.Context, req api.CreateMapfixAuditCommentReq, params api.CreateMapfixAuditCommentParams) (error) {
|
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !ok {
|
|
||||||
return ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleMapfixReview()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
userId, err := userInfo.GetUserID()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has_role {
|
|
||||||
// Submitter has special permission to comment on their mapfix
|
|
||||||
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if mapfix.Submitter != userId {
|
|
||||||
return ErrPermissionDeniedNeedRoleMapfixReview
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data := []byte{}
|
|
||||||
_, err = req.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
Comment := string(data)
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataComment{
|
|
||||||
Comment: Comment,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
|
||||||
ID: 0,
|
|
||||||
User: userId,
|
|
||||||
ResourceType: model.ResourceMapfix,
|
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeComment,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMapfixAuditEvents invokes listMapfixAuditEvents operation.
|
|
||||||
//
|
|
||||||
// Retrieve a list of audit events.
|
|
||||||
//
|
|
||||||
// GET /mapfixes/{MapfixID}/audit-events
|
|
||||||
func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMapfixAuditEventsParams) ([]api.AuditEvent, error) {
|
|
||||||
filter := datastore.Optional()
|
filter := datastore.Optional()
|
||||||
|
|
||||||
filter.Add("resource_type", model.ResourceMapfix)
|
filter.Add("resource_type", resource.Type)
|
||||||
filter.Add("resource_id", params.MapfixID)
|
filter.Add("resource_id", resource.ID)
|
||||||
|
|
||||||
items, err := svc.DB.AuditEvents().List(ctx, filter, model.Page{
|
items, err := svc.DB.AuditEvents().List(ctx, filter, page)
|
||||||
Number: params.Page,
|
|
||||||
Size: params.Limit,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -140,50 +68,7 @@ func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMa
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.
|
func (svc *Service) CreateAuditEventAction(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataAction) error {
|
||||||
//
|
|
||||||
// Post a comment to the audit log
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/comment
|
|
||||||
func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.CreateSubmissionAuditCommentReq, params api.CreateSubmissionAuditCommentParams) (error) {
|
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !ok {
|
|
||||||
return ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleSubmissionReview()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
userId, err := userInfo.GetUserID()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has_role {
|
|
||||||
// Submitter has special permission to comment on their submission
|
|
||||||
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if submission.Submitter != userId {
|
|
||||||
return ErrPermissionDeniedNeedRoleSubmissionReview
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data := []byte{}
|
|
||||||
_, err = req.Read(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
Comment := string(data)
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataComment{
|
|
||||||
Comment: Comment,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
EventData, err := json.Marshal(event_data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -192,8 +77,29 @@ func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.Cr
|
|||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
User: userId,
|
User: userId,
|
||||||
ResourceType: model.ResourceSubmission,
|
ResourceType: resource.Type,
|
||||||
ResourceID: params.SubmissionID,
|
ResourceID: resource.ID,
|
||||||
|
EventType: model.AuditEventTypeAction,
|
||||||
|
EventData: EventData,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *Service) CreateAuditEventComment(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataComment) error {
|
||||||
|
EventData, err := json.Marshal(event_data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
|
ResourceType: resource.Type,
|
||||||
|
ResourceID: resource.ID,
|
||||||
EventType: model.AuditEventTypeComment,
|
EventType: model.AuditEventTypeComment,
|
||||||
EventData: EventData,
|
EventData: EventData,
|
||||||
})
|
})
|
||||||
@@ -204,68 +110,23 @@ func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.Cr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListSubmissionAuditEvents invokes listSubmissionAuditEvents operation.
|
func (svc *Service) CreateAuditEventChangeModel(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataChangeModel) error {
|
||||||
//
|
EventData, err := json.Marshal(event_data)
|
||||||
// Retrieve a list of audit events.
|
if err != nil {
|
||||||
//
|
return err
|
||||||
// GET /submissions/{SubmissionID}/audit-events
|
}
|
||||||
func (svc *Service) ListSubmissionAuditEvents(ctx context.Context, params api.ListSubmissionAuditEventsParams) ([]api.AuditEvent, error) {
|
|
||||||
filter := datastore.Optional()
|
|
||||||
|
|
||||||
filter.Add("resource_type", model.ResourceSubmission)
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
filter.Add("resource_id", params.SubmissionID)
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
items, err := svc.DB.AuditEvents().List(ctx, filter, model.Page{
|
ResourceType: resource.Type,
|
||||||
Number: params.Page,
|
ResourceID: resource.ID,
|
||||||
Size: params.Limit,
|
EventType: model.AuditEventTypeChangeModel,
|
||||||
|
EventData: EventData,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
idMap := make(map[int64]bool)
|
return nil
|
||||||
for _, item := range items {
|
|
||||||
idMap[int64(item.User)] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var idList users.IdList
|
|
||||||
idList.ID = make([]int64,len(idMap))
|
|
||||||
for userId := range idMap {
|
|
||||||
idList.ID = append(idList.ID, userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
userList, err := svc.Users.GetList(ctx, &idList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userMap := make(map[int64]*users.UserResponse)
|
|
||||||
for _,user := range userList.Users {
|
|
||||||
userMap[user.ID] = user
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp []api.AuditEvent
|
|
||||||
for _, item := range items {
|
|
||||||
EventData := api.AuditEventEventData{}
|
|
||||||
err = EventData.UnmarshalJSON(item.EventData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
username := ""
|
|
||||||
if userMap[int64(item.User)] != nil {
|
|
||||||
username = userMap[int64(item.User)].Username
|
|
||||||
}
|
|
||||||
resp = append(resp, api.AuditEvent{
|
|
||||||
ID: item.ID,
|
|
||||||
Date: item.CreatedAt.Unix(),
|
|
||||||
User: int64(item.User),
|
|
||||||
Username: username,
|
|
||||||
ResourceType: int32(item.ResourceType),
|
|
||||||
ResourceID: item.ResourceID,
|
|
||||||
EventType: int32(item.EventType),
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
@@ -298,24 +299,15 @@ func (svc *Service) UpdateMapfixModel(ctx context.Context, params api.UpdateMapf
|
|||||||
NewModelVersion: NewModelVersion,
|
NewModelVersion: NewModelVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventChangeModel(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeChangeModel,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixReject invokes actionMapfixReject operation.
|
// ActionMapfixReject invokes actionMapfixReject operation.
|
||||||
@@ -356,24 +348,15 @@ func (svc *Service) ActionMapfixReject(ctx context.Context, params api.ActionMap
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixRequestChanges invokes actionMapfixRequestChanges operation.
|
// ActionMapfixRequestChanges invokes actionMapfixRequestChanges operation.
|
||||||
@@ -396,10 +379,33 @@ func (svc *Service) ActionMapfixRequestChanges(ctx context.Context, params api.A
|
|||||||
return ErrPermissionDeniedNeedRoleMapfixReview
|
return ErrPermissionDeniedNeedRoleMapfixReview
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userId, err := userInfo.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
|
target_status := model.MapfixStatusChangesRequested
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", model.MapfixStatusChangesRequested)
|
smap.Add("status_id", target_status)
|
||||||
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidated, model.MapfixStatusAcceptedUnvalidated, model.MapfixStatusSubmitted}, smap)
|
err = svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidated, model.MapfixStatusAcceptedUnvalidated, model.MapfixStatusSubmitted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
event_data := model.AuditEventDataAction{
|
||||||
|
TargetStatus: uint32(target_status),
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.CreateAuditEventAction(
|
||||||
|
ctx,
|
||||||
|
userId,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
|
Type: model.ResourceMapfix,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixRevoke invokes actionMapfixRevoke operation.
|
// ActionMapfixRevoke invokes actionMapfixRevoke operation.
|
||||||
@@ -443,24 +449,15 @@ func (svc *Service) ActionMapfixRevoke(ctx context.Context, params api.ActionMap
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerSubmit invokes actionMapfixTriggerSubmit operation.
|
// ActionMapfixTriggerSubmit invokes actionMapfixTriggerSubmit operation.
|
||||||
@@ -501,8 +498,9 @@ func (svc *Service) ActionMapfixTriggerSubmit(ctx context.Context, params api.Ac
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate_request := model.CheckMapfixRequest{
|
validate_request := model.CheckMapfixRequest{
|
||||||
MapfixID: mapfix.ID,
|
MapfixID: mapfix.ID,
|
||||||
ModelID: mapfix.AssetID,
|
ModelID: mapfix.AssetID,
|
||||||
|
SkipChecks: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
j, err := json.Marshal(validate_request)
|
j, err := json.Marshal(validate_request)
|
||||||
@@ -519,32 +517,23 @@ func (svc *Service) ActionMapfixTriggerSubmit(ctx context.Context, params api.Ac
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixBypassSubmit invokes actionMapfixBypassSubmit operation.
|
// ActionMapfixTriggerSubmitUnchecked invokes actionMapfixTriggerSubmitUnchecked operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/bypass-submit
|
// POST /mapfixes/{MapfixID}/status/trigger-submit-unchecked
|
||||||
func (svc *Service) ActionMapfixBypassSubmit(ctx context.Context, params api.ActionMapfixBypassSubmitParams) error {
|
func (svc *Service) ActionMapfixTriggerSubmitUnchecked(ctx context.Context, params api.ActionMapfixTriggerSubmitUncheckedParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
@@ -577,7 +566,7 @@ func (svc *Service) ActionMapfixBypassSubmit(ctx context.Context, params api.Act
|
|||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
target_status := model.MapfixStatusSubmitted
|
target_status := model.MapfixStatusSubmitting
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", target_status)
|
smap.Add("status_id", target_status)
|
||||||
err = svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusChangesRequested}, smap)
|
err = svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusChangesRequested}, smap)
|
||||||
@@ -585,28 +574,35 @@ func (svc *Service) ActionMapfixBypassSubmit(ctx context.Context, params api.Act
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_request := model.CheckMapfixRequest{
|
||||||
|
MapfixID: mapfix.ID,
|
||||||
|
ModelID: mapfix.AssetID,
|
||||||
|
SkipChecks: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.Nats.Publish("maptest.mapfixes.check", []byte(j))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixResetSubmitting implements actionMapfixResetSubmitting operation.
|
// ActionMapfixResetSubmitting implements actionMapfixResetSubmitting operation.
|
||||||
@@ -654,24 +650,15 @@ func (svc *Service) ActionMapfixResetSubmitting(ctx context.Context, params api.
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
||||||
@@ -730,24 +717,15 @@ func (svc *Service) ActionMapfixTriggerUpload(ctx context.Context, params api.Ac
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
||||||
@@ -798,24 +776,15 @@ func (svc *Service) ActionMapfixValidated(ctx context.Context, params api.Action
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerValidate invokes actionMapfixTriggerValidate operation.
|
// ActionMapfixTriggerValidate invokes actionMapfixTriggerValidate operation.
|
||||||
@@ -907,24 +876,15 @@ func (svc *Service) ActionMapfixTriggerValidate(ctx context.Context, params api.
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixRetryValidate invokes actionMapfixRetryValidate operation.
|
// ActionMapfixRetryValidate invokes actionMapfixRetryValidate operation.
|
||||||
@@ -987,24 +947,15 @@ func (svc *Service) ActionMapfixRetryValidate(ctx context.Context, params api.Ac
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
||||||
@@ -1055,22 +1006,85 @@ func (svc *Service) ActionMapfixAccepted(ctx context.Context, params api.ActionM
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
}
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
// CreateMapfixAuditComment implements createMapfixAuditComment operation.
|
||||||
})
|
//
|
||||||
if err != nil {
|
// Post a comment to the audit log
|
||||||
return err
|
//
|
||||||
}
|
// POST /mapfixes/{MapfixID}/comment
|
||||||
|
func (svc *Service) CreateMapfixAuditComment(ctx context.Context, req api.CreateMapfixAuditCommentReq, params api.CreateMapfixAuditCommentParams) (error) {
|
||||||
return nil
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userId, err := userInfo.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has_role {
|
||||||
|
// Submitter has special permission to comment on their mapfix
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if mapfix.Submitter != userId {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapfixReview
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
event_data := model.AuditEventDataComment{
|
||||||
|
Comment: string(data),
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.CreateAuditEventComment(
|
||||||
|
ctx,
|
||||||
|
userId,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
|
Type: model.ResourceMapfix,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMapfixAuditEvents invokes listMapfixAuditEvents operation.
|
||||||
|
//
|
||||||
|
// Retrieve a list of audit events.
|
||||||
|
//
|
||||||
|
// GET /mapfixes/{MapfixID}/audit-events
|
||||||
|
func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMapfixAuditEventsParams) ([]api.AuditEvent, error) {
|
||||||
|
return svc.ListAuditEvents(
|
||||||
|
ctx,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
|
Type: model.ResourceMapfix,
|
||||||
|
},
|
||||||
|
model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"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/roblox"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListMaps implements listMaps operation.
|
// ListMaps implements listMaps operation.
|
||||||
@@ -71,3 +73,29 @@ func (svc *Service) GetMap(ctx context.Context, params api.GetMapParams) (*api.M
|
|||||||
Date: mapResponse.Date,
|
Date: mapResponse.Date,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMapAssetLocation invokes getMapAssetLocation operation.
|
||||||
|
//
|
||||||
|
// Get location of map asset.
|
||||||
|
//
|
||||||
|
// GET /maps/{MapID}/location
|
||||||
|
func (svc *Service) GetMapAssetLocation(ctx context.Context, params api.GetMapAssetLocationParams) (ok api.GetMapAssetLocationOK, err error) {
|
||||||
|
// Ensure map exists in the db!
|
||||||
|
// This could otherwise be used to access any asset
|
||||||
|
_, err = svc.Maps.Get(ctx, &maps.IdMessage{
|
||||||
|
ID: params.MapID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := svc.Roblox.GetAssetLocation(roblox.GetAssetLatestRequest{
|
||||||
|
AssetID: uint64(params.MapID),
|
||||||
|
})
|
||||||
|
if err != nil{
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ok.Data = strings.NewReader(info.Location)
|
||||||
|
return ok, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParam
|
|||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
resp = append(resp, api.Script{
|
resp = append(resp, api.Script{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
|
Name: item.Name,
|
||||||
Hash: model.HashFormat(uint64(item.Hash)),
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
Source: item.Source,
|
Source: item.Source,
|
||||||
ResourceType: int32(item.ResourceType),
|
ResourceType: int32(item.ResourceType),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"git.itzana.me/strafesnet/go-grpc/users"
|
"git.itzana.me/strafesnet/go-grpc/users"
|
||||||
"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/roblox"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ type Service struct {
|
|||||||
Nats nats.JetStreamContext
|
Nats nats.JetStreamContext
|
||||||
Maps maps.MapsServiceClient
|
Maps maps.MapsServiceClient
|
||||||
Users users.UsersServiceClient
|
Users users.UsersServiceClient
|
||||||
|
Roblox roblox.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewError creates *ErrorStatusCode from error returned by handler.
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
@@ -365,24 +366,15 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
|
|||||||
NewModelVersion: NewModelVersion,
|
NewModelVersion: NewModelVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventChangeModel(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: submission.ID,
|
|
||||||
EventType: model.AuditEventTypeChangeModel,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
@@ -423,24 +415,15 @@ func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.Actio
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
||||||
@@ -481,24 +464,15 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params a
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
||||||
@@ -542,24 +516,15 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerSubmit invokes actionSubmissionTriggerSubmit operation.
|
// ActionSubmissionTriggerSubmit invokes actionSubmissionTriggerSubmit operation.
|
||||||
@@ -610,6 +575,7 @@ func (svc *Service) ActionSubmissionTriggerSubmit(ctx context.Context, params ap
|
|||||||
validate_request := model.CheckSubmissionRequest{
|
validate_request := model.CheckSubmissionRequest{
|
||||||
SubmissionID: submission.ID,
|
SubmissionID: submission.ID,
|
||||||
ModelID: submission.AssetID,
|
ModelID: submission.AssetID,
|
||||||
|
SkipChecks: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
j, err := json.Marshal(validate_request)
|
j, err := json.Marshal(validate_request)
|
||||||
@@ -626,32 +592,23 @@ func (svc *Service) ActionSubmissionTriggerSubmit(ctx context.Context, params ap
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionBypassSubmit invokes actionSubmissionBypassSubmit operation.
|
// ActionSubmissionTriggerSubmitUnchecked invokes actionSubmissionTriggerSubmitUnchecked operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer changes status from ChangesRequested -> Submitted.
|
// Role Reviewer changes status from ChangesRequested -> Submitting.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/bypass-submit
|
// POST /submissions/{SubmissionID}/status/trigger-submit-unchecked
|
||||||
func (svc *Service) ActionSubmissionBypassSubmit(ctx context.Context, params api.ActionSubmissionBypassSubmitParams) error {
|
func (svc *Service) ActionSubmissionTriggerSubmitUnchecked(ctx context.Context, params api.ActionSubmissionTriggerSubmitUncheckedParams) error {
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrUserInfo
|
return ErrUserInfo
|
||||||
@@ -684,7 +641,7 @@ func (svc *Service) ActionSubmissionBypassSubmit(ctx context.Context, params api
|
|||||||
}
|
}
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
target_status := model.SubmissionStatusSubmitted
|
target_status := model.SubmissionStatusSubmitting
|
||||||
smap := datastore.Optional()
|
smap := datastore.Optional()
|
||||||
smap.Add("status_id", target_status)
|
smap.Add("status_id", target_status)
|
||||||
err = svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusChangesRequested}, smap)
|
err = svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusChangesRequested}, smap)
|
||||||
@@ -692,28 +649,35 @@ func (svc *Service) ActionSubmissionBypassSubmit(ctx context.Context, params api
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_request := model.CheckSubmissionRequest{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
ModelID: submission.AssetID,
|
||||||
|
SkipChecks: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.Nats.Publish("maptest.submissions.check", []byte(j))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionResetSubmitting implements actionSubmissionResetSubmitting operation.
|
// ActionSubmissionResetSubmitting implements actionSubmissionResetSubmitting operation.
|
||||||
@@ -761,24 +725,15 @@ func (svc *Service) ActionSubmissionResetSubmitting(ctx context.Context, params
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
||||||
@@ -844,24 +799,15 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
@@ -912,24 +858,15 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.Ac
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
||||||
@@ -1004,24 +941,15 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRetryValidate invokes actionSubmissionRetryValidate operation.
|
// ActionSubmissionRetryValidate invokes actionSubmissionRetryValidate operation.
|
||||||
@@ -1084,24 +1012,15 @@ func (svc *Service) ActionSubmissionRetryValidate(ctx context.Context, params ap
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
@@ -1152,24 +1071,15 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.Act
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
userId,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: userId,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReleaseSubmissions invokes releaseSubmissions operation.
|
// ReleaseSubmissions invokes releaseSubmissions operation.
|
||||||
@@ -1239,3 +1149,75 @@ func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.Releas
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.
|
||||||
|
//
|
||||||
|
// Post a comment to the audit log
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/comment
|
||||||
|
func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.CreateSubmissionAuditCommentReq, params api.CreateSubmissionAuditCommentParams) (error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userId, err := userInfo.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has_role {
|
||||||
|
// Submitter has special permission to comment on their submission
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if submission.Submitter != userId {
|
||||||
|
return ErrPermissionDeniedNeedRoleSubmissionReview
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
event_data := model.AuditEventDataComment{
|
||||||
|
Comment: string(data),
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.CreateAuditEventComment(
|
||||||
|
ctx,
|
||||||
|
userId,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
|
Type: model.ResourceSubmission,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSubmissionAuditEvents invokes listSubmissionAuditEvents operation.
|
||||||
|
//
|
||||||
|
// Retrieve a list of audit events.
|
||||||
|
//
|
||||||
|
// GET /submissions/{SubmissionID}/audit-events
|
||||||
|
func (svc *Service) ListSubmissionAuditEvents(ctx context.Context, params api.ListSubmissionAuditEventsParams) ([]api.AuditEvent, error) {
|
||||||
|
return svc.ListAuditEvents(
|
||||||
|
ctx,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
|
Type: model.ResourceSubmission,
|
||||||
|
},
|
||||||
|
model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
92
pkg/service_internal/audit_events.go
Normal file
92
pkg/service_internal/audit_events.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (svc *Service) CreateAuditEventAction(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataAction) error {
|
||||||
|
EventData, err := json.Marshal(event_data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
|
ResourceType: resource.Type,
|
||||||
|
ResourceID: resource.ID,
|
||||||
|
EventType: model.AuditEventTypeAction,
|
||||||
|
EventData: EventData,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *Service) CreateAuditEventChangeValidatedModel(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataChangeValidatedModel) error {
|
||||||
|
EventData, err := json.Marshal(event_data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
|
ResourceType: resource.Type,
|
||||||
|
ResourceID: resource.ID,
|
||||||
|
EventType: model.AuditEventTypeChangeValidatedModel,
|
||||||
|
EventData: EventData,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *Service) CreateAuditEventError(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataError) error {
|
||||||
|
EventData, err := json.Marshal(event_data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
|
ResourceType: resource.Type,
|
||||||
|
ResourceID: resource.ID,
|
||||||
|
EventType: model.AuditEventTypeError,
|
||||||
|
EventData: EventData,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *Service) CreateAuditEventCheckList(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataCheckList) error {
|
||||||
|
EventData, err := json.Marshal(event_data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
||||||
|
ID: 0,
|
||||||
|
User: userId,
|
||||||
|
ResourceType: resource.Type,
|
||||||
|
ResourceID: resource.ID,
|
||||||
|
EventType: model.AuditEventTypeCheckList,
|
||||||
|
EventData: EventData,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package service_internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@@ -54,24 +53,15 @@ func (svc *Service) UpdateMapfixValidatedModel(ctx context.Context, params inter
|
|||||||
ValidatedModelVersion: ValidatedModelVersion,
|
ValidatedModelVersion: ValidatedModelVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventChangeValidatedModel(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeChangeValidatedModel,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixSubmitted invokes actionMapfixSubmitted operation.
|
// ActionMapfixSubmitted invokes actionMapfixSubmitted operation.
|
||||||
@@ -97,24 +87,15 @@ func (svc *Service) ActionMapfixSubmitted(ctx context.Context, params internal.A
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
|
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
|
||||||
@@ -132,51 +113,19 @@ func (svc *Service) ActionMapfixRequestChanges(ctx context.Context, params inter
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
|
||||||
ID: 0,
|
|
||||||
User: ValidtorUserID,
|
|
||||||
ResourceType: model.ResourceMapfix,
|
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeError,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
||||||
@@ -206,53 +155,20 @@ func (svc *Service) ActionMapfixAccepted(ctx context.Context, params internal.Ac
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//push an error audit event
|
|
||||||
{
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
|
||||||
ID: 0,
|
|
||||||
User: ValidtorUserID,
|
|
||||||
ResourceType: model.ResourceMapfix,
|
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeError,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
// push an action audit event
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceMapfix,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceMapfix,
|
)
|
||||||
ResourceID: params.MapfixID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
||||||
@@ -274,24 +190,66 @@ func (svc *Service) ActionMapfixUploaded(ctx context.Context, params internal.Ac
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
|
Type: model.ResourceMapfix,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditError implements createMapfixAuditError operation.
|
||||||
|
//
|
||||||
|
// Post an error to the audit log
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/error
|
||||||
|
func (svc *Service) CreateMapfixAuditError(ctx context.Context, params internal.CreateMapfixAuditErrorParams) (error) {
|
||||||
|
event_data := model.AuditEventDataError{
|
||||||
|
Error: params.ErrorMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
return svc.CreateAuditEventError(
|
||||||
ID: 0,
|
ctx,
|
||||||
User: ValidtorUserID,
|
ValidtorUserID,
|
||||||
ResourceType: model.ResourceMapfix,
|
model.Resource{
|
||||||
ResourceID: params.MapfixID,
|
ID: params.MapfixID,
|
||||||
EventType: model.AuditEventTypeAction,
|
Type: model.ResourceMapfix,
|
||||||
EventData: EventData,
|
},
|
||||||
})
|
event_data,
|
||||||
if err != nil {
|
)
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Post a checklist to the audit log
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/checklist
|
||||||
|
func (svc *Service) CreateMapfixAuditCheckList(ctx context.Context, check_list internal.CheckList, params internal.CreateMapfixAuditCheckListParams) (error) {
|
||||||
|
check_list2 := make([]model.Check, len(check_list))
|
||||||
|
for i, check := range check_list {
|
||||||
|
check_list2[i] = model.Check{
|
||||||
|
Name: check.Name,
|
||||||
|
Summary: check.Summary,
|
||||||
|
Passed: check.Passed,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
event_data := model.AuditEventDataCheckList{
|
||||||
|
CheckList: check_list2,
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.CreateAuditEventCheckList(
|
||||||
|
ctx,
|
||||||
|
ValidtorUserID,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.MapfixID,
|
||||||
|
Type: model.ResourceMapfix,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST /mapfixes
|
// POST /mapfixes
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParam
|
|||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
resp = append(resp, api.Script{
|
resp = append(resp, api.Script{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
|
Name: item.Name,
|
||||||
Hash: model.HashFormat(uint64(item.Hash)),
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
Source: item.Source,
|
Source: item.Source,
|
||||||
ResourceType: int32(item.ResourceType),
|
ResourceType: int32(item.ResourceType),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package service_internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@@ -54,24 +53,15 @@ func (svc *Service) UpdateSubmissionValidatedModel(ctx context.Context, params i
|
|||||||
ValidatedModelVersion: ValidatedModelVersion,
|
ValidatedModelVersion: ValidatedModelVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventChangeValidatedModel(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeChangeValidatedModel,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionSubmitted invokes actionSubmissionSubmitted operation.
|
// ActionSubmissionSubmitted invokes actionSubmissionSubmitted operation.
|
||||||
@@ -97,24 +87,15 @@ func (svc *Service) ActionSubmissionSubmitted(ctx context.Context, params intern
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
|
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
|
||||||
@@ -132,53 +113,20 @@ func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params i
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//push an error audit event
|
|
||||||
{
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
|
||||||
ID: 0,
|
|
||||||
User: ValidtorUserID,
|
|
||||||
ResourceType: model.ResourceSubmission,
|
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeError,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
// push an action audit event
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
@@ -200,24 +148,15 @@ func (svc *Service) ActionSubmissionValidated(ctx context.Context, params intern
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
@@ -235,54 +174,20 @@ func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params interna
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//push an error audit event
|
|
||||||
{
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
|
||||||
ID: 0,
|
|
||||||
User: ValidtorUserID,
|
|
||||||
ResourceType: model.ResourceSubmission,
|
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeError,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
// push an action audit event
|
||||||
event_data := model.AuditEventDataAction{
|
event_data := model.AuditEventDataAction{
|
||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
}
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
Type: model.ResourceSubmission,
|
||||||
ID: 0,
|
},
|
||||||
User: ValidtorUserID,
|
event_data,
|
||||||
ResourceType: model.ResourceSubmission,
|
)
|
||||||
ResourceID: params.SubmissionID,
|
|
||||||
EventType: model.AuditEventTypeAction,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
@@ -305,24 +210,66 @@ func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params interna
|
|||||||
TargetStatus: uint32(target_status),
|
TargetStatus: uint32(target_status),
|
||||||
}
|
}
|
||||||
|
|
||||||
EventData, err := json.Marshal(event_data)
|
return svc.CreateAuditEventAction(
|
||||||
if err != nil {
|
ctx,
|
||||||
return err
|
ValidtorUserID,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
|
Type: model.ResourceSubmission,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
|
||||||
|
//
|
||||||
|
// Post an error to the audit log
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/error
|
||||||
|
func (svc *Service) CreateSubmissionAuditError(ctx context.Context, params internal.CreateSubmissionAuditErrorParams) (error) {
|
||||||
|
event_data := model.AuditEventDataError{
|
||||||
|
Error: params.ErrorMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
|
return svc.CreateAuditEventError(
|
||||||
ID: 0,
|
ctx,
|
||||||
User: ValidtorUserID,
|
ValidtorUserID,
|
||||||
ResourceType: model.ResourceSubmission,
|
model.Resource{
|
||||||
ResourceID: params.SubmissionID,
|
ID: params.SubmissionID,
|
||||||
EventType: model.AuditEventTypeAction,
|
Type: model.ResourceSubmission,
|
||||||
EventData: EventData,
|
},
|
||||||
})
|
event_data,
|
||||||
if err != nil {
|
)
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
|
||||||
|
//
|
||||||
|
// Post a checklist to the audit log
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/checklist
|
||||||
|
func (svc *Service) CreateSubmissionAuditCheckList(ctx context.Context, check_list internal.CheckList, params internal.CreateSubmissionAuditCheckListParams) (error) {
|
||||||
|
check_list2 := make([]model.Check, len(check_list))
|
||||||
|
for i, check := range check_list {
|
||||||
|
check_list2[i] = model.Check{
|
||||||
|
Name: check.Name,
|
||||||
|
Summary: check.Summary,
|
||||||
|
Passed: check.Passed,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
event_data := model.AuditEventDataCheckList{
|
||||||
|
CheckList: check_list2,
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.CreateAuditEventCheckList(
|
||||||
|
ctx,
|
||||||
|
ValidtorUserID,
|
||||||
|
model.Resource{
|
||||||
|
ID: params.SubmissionID,
|
||||||
|
Type: model.ResourceSubmission,
|
||||||
|
},
|
||||||
|
event_data,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST /submissions
|
// POST /submissions
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "submissions-api"
|
name = "submissions-api"
|
||||||
version = "0.7.2"
|
version = "0.8.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"
|
||||||
@@ -11,6 +11,7 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
chrono = { version = "0.4.41", features = ["serde"] }
|
||||||
reqwest = { version = "0", features = ["json"] }
|
reqwest = { version = "0", features = ["json"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl Context{
|
|||||||
if let Some(resource_type)=config.ResourceType{
|
if let Some(resource_type)=config.ResourceType{
|
||||||
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
|
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
|
||||||
}
|
}
|
||||||
if let Some(resource_id)=config.ResourceID{
|
if let Some(ResourceID(resource_id))=config.ResourceID{
|
||||||
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
|
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
pub async fn get_script_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptResponse>,SingleItemError>{
|
pub async fn get_script_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptResponse>,ScriptSingleItemError>{
|
||||||
let scripts=self.get_scripts(GetScriptsRequest{
|
let scripts=self.get_scripts(GetScriptsRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -57,7 +57,7 @@ impl Context{
|
|||||||
ResourceID:None,
|
ResourceID:None,
|
||||||
}).await.map_err(SingleItemError::Other)?;
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
if 1<scripts.len(){
|
if 1<scripts.len(){
|
||||||
return Err(SingleItemError::DuplicateItems);
|
return Err(SingleItemError::DuplicateItems(scripts.into_iter().map(|item|item.ID).collect()));
|
||||||
}
|
}
|
||||||
Ok(scripts.into_iter().next())
|
Ok(scripts.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
pub async fn get_script_policy_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptPolicyResponse>,SingleItemError>{
|
pub async fn get_script_policy_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptPolicyResponse>,ScriptPolicySingleItemError>{
|
||||||
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -115,7 +115,7 @@ impl Context{
|
|||||||
Policy:None,
|
Policy:None,
|
||||||
}).await.map_err(SingleItemError::Other)?;
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
if 1<policies.len(){
|
if 1<policies.len(){
|
||||||
return Err(SingleItemError::DuplicateItems);
|
return Err(SingleItemError::DuplicateItems(policies.into_iter().map(|item|item.ID).collect()));
|
||||||
}
|
}
|
||||||
Ok(policies.into_iter().next())
|
Ok(policies.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -150,6 +150,84 @@ impl Context{
|
|||||||
self.0.delete(url).await.map_err(Error::Reqwest)?
|
self.0.delete(url).await.map_err(Error::Reqwest)?
|
||||||
).await.map_err(Error::Response)?;
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub async fn get_submissions(&self,config:GetSubmissionsRequest<'_>)->Result<SubmissionsResponse,Error>{
|
||||||
|
let url_raw=format!("{}/submissions",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(sort)=config.Sort{
|
||||||
|
query_pairs.append_pair("Sort",(sort as u8).to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(display_name)=config.DisplayName{
|
||||||
|
query_pairs.append_pair("DisplayName",display_name);
|
||||||
|
}
|
||||||
|
if let Some(creator)=config.Creator{
|
||||||
|
query_pairs.append_pair("Creator",creator);
|
||||||
|
}
|
||||||
|
if let Some(game_id)=config.GameID{
|
||||||
|
query_pairs.append_pair("GameID",(game_id as u8).to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(submitter)=config.Submitter{
|
||||||
|
query_pairs.append_pair("Submitter",submitter.to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(asset_id)=config.AssetID{
|
||||||
|
query_pairs.append_pair("AssetID",asset_id.to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(uploaded_asset_id)=config.UploadedAssetID{
|
||||||
|
query_pairs.append_pair("UploadedAssetID",uploaded_asset_id.to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(status_id)=config.StatusID{
|
||||||
|
query_pairs.append_pair("StatusID",(status_id as u8).to_string().as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.get(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn get_maps(&self,config:GetMapsRequest<'_>)->Result<Vec<MapResponse>,Error>{
|
||||||
|
let url_raw=format!("{}/maps",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(sort)=config.Sort{
|
||||||
|
query_pairs.append_pair("Sort",(sort as u8).to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(display_name)=config.DisplayName{
|
||||||
|
query_pairs.append_pair("DisplayName",display_name);
|
||||||
|
}
|
||||||
|
if let Some(creator)=config.Creator{
|
||||||
|
query_pairs.append_pair("Creator",creator);
|
||||||
|
}
|
||||||
|
if let Some(game_id)=config.GameID{
|
||||||
|
query_pairs.append_pair("GameID",(game_id as u8).to_string().as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.get(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn release_submissions(&self,config:ReleaseRequest<'_>)->Result<(),Error>{
|
||||||
|
let url_raw=format!("{}/release-submissions",self.0.base_url);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(config.schedule).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl Context{
|
|||||||
if let Some(resource_type)=config.ResourceType{
|
if let Some(resource_type)=config.ResourceType{
|
||||||
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
|
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
|
||||||
}
|
}
|
||||||
if let Some(resource_id)=config.ResourceID{
|
if let Some(ResourceID(resource_id))=config.ResourceID{
|
||||||
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
|
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
pub async fn get_script_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptResponse>,SingleItemError>{
|
pub async fn get_script_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptResponse>,ScriptSingleItemError>{
|
||||||
let scripts=self.get_scripts(GetScriptsRequest{
|
let scripts=self.get_scripts(GetScriptsRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -87,7 +87,7 @@ impl Context{
|
|||||||
ResourceID:None,
|
ResourceID:None,
|
||||||
}).await.map_err(SingleItemError::Other)?;
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
if 1<scripts.len(){
|
if 1<scripts.len(){
|
||||||
return Err(SingleItemError::DuplicateItems);
|
return Err(SingleItemError::DuplicateItems(scripts.into_iter().map(|item|item.ID).collect()));
|
||||||
}
|
}
|
||||||
Ok(scripts.into_iter().next())
|
Ok(scripts.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
pub async fn get_script_policy_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptPolicyResponse>,SingleItemError>{
|
pub async fn get_script_policy_from_hash(&self,config:HashRequest<'_>)->Result<Option<ScriptPolicyResponse>,ScriptPolicySingleItemError>{
|
||||||
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -135,7 +135,7 @@ impl Context{
|
|||||||
Policy:None,
|
Policy:None,
|
||||||
}).await.map_err(SingleItemError::Other)?;
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
if 1<policies.len(){
|
if 1<policies.len(){
|
||||||
return Err(SingleItemError::DuplicateItems);
|
return Err(SingleItemError::DuplicateItems(policies.into_iter().map(|item|item.ID).collect()));
|
||||||
}
|
}
|
||||||
Ok(policies.into_iter().next())
|
Ok(policies.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -161,25 +161,36 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
|
pub async fn create_submission_audit_check_list(&self,config:CreateSubmissionAuditCheckListRequest<'_>)->Result<(),Error>{
|
||||||
|
let url_raw=format!("{}/submissions/{}/checklist",self.0.base_url,config.SubmissionID.0);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config.CheckList).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
// simple submission endpoints
|
// simple submission endpoints
|
||||||
action!("submissions",action_submission_request_changes,config,ActionSubmissionRequestChangesRequest,"status/validator-request-changes",config.SubmissionID,
|
action!("submissions",action_submission_request_changes,config,ActionSubmissionRequestChangesRequest,"status/validator-request-changes",config.SubmissionID.0,);
|
||||||
("ErrorMessage",config.ErrorMessage.as_str())
|
action!("submissions",action_submission_submitted,config,ActionSubmissionSubmittedRequest,"status/validator-submitted",config.SubmissionID.0,
|
||||||
);
|
|
||||||
action!("submissions",action_submission_submitted,config,ActionSubmissionSubmittedRequest,"status/validator-submitted",config.SubmissionID,
|
|
||||||
("ModelVersion",config.ModelVersion.to_string().as_str())
|
("ModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
("DisplayName",config.DisplayName.as_str())
|
("DisplayName",config.DisplayName.as_str())
|
||||||
("Creator",config.Creator.as_str())
|
("Creator",config.Creator.as_str())
|
||||||
("GameID",config.GameID.to_string().as_str())
|
("GameID",(config.GameID as u8).to_string().as_str())
|
||||||
);
|
);
|
||||||
action!("submissions",action_submission_validated,config,SubmissionID,"status/validator-validated",config.0,);
|
action!("submissions",action_submission_validated,config,SubmissionID,"status/validator-validated",config.0,);
|
||||||
action!("submissions",update_submission_validated_model,config,UpdateSubmissionModelRequest,"validated-model",config.SubmissionID,
|
action!("submissions",update_submission_validated_model,config,UpdateSubmissionModelRequest,"validated-model",config.SubmissionID.0,
|
||||||
("ValidatedModelID",config.ModelID.to_string().as_str())
|
("ValidatedModelID",config.ModelID.to_string().as_str())
|
||||||
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
);
|
);
|
||||||
action!("submissions",action_submission_uploaded,config,ActionSubmissionUploadedRequest,"status/validator-uploaded",config.SubmissionID,
|
action!("submissions",action_submission_uploaded,config,ActionSubmissionUploadedRequest,"status/validator-uploaded",config.SubmissionID.0,
|
||||||
("UploadedAssetID",config.UploadedAssetID.to_string().as_str())
|
("UploadedAssetID",config.UploadedAssetID.to_string().as_str())
|
||||||
);
|
);
|
||||||
action!("submissions",action_submission_accepted,config,ActionSubmissionAcceptedRequest,"status/validator-failed",config.SubmissionID,
|
action!("submissions",action_submission_accepted,config,ActionSubmissionAcceptedRequest,"status/validator-failed",config.SubmissionID.0,);
|
||||||
|
action!("submissions",create_submission_audit_error,config,CreateSubmissionAuditErrorRequest,"error",config.SubmissionID.0,
|
||||||
("ErrorMessage",config.ErrorMessage.as_str())
|
("ErrorMessage",config.ErrorMessage.as_str())
|
||||||
);
|
);
|
||||||
pub async fn create_mapfix(&self,config:CreateMapfixRequest<'_>)->Result<MapfixIDResponse,Error>{
|
pub async fn create_mapfix(&self,config:CreateMapfixRequest<'_>)->Result<MapfixIDResponse,Error>{
|
||||||
@@ -193,27 +204,38 @@ impl Context{
|
|||||||
).await.map_err(Error::Response)?
|
).await.map_err(Error::Response)?
|
||||||
.json().await.map_err(Error::ReqwestJson)
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
}
|
}
|
||||||
|
pub async fn create_mapfix_audit_check_list(&self,config:CreateMapfixAuditCheckListRequest<'_>)->Result<(),Error>{
|
||||||
|
let url_raw=format!("{}/mapfixes/{}/checklist",self.0.base_url,config.MapfixID.0);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config.CheckList).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
// simple mapfixes endpoints
|
// simple mapfixes endpoints
|
||||||
action!("mapfixes",action_mapfix_request_changes,config,ActionMapfixRequestChangesRequest,"status/validator-request-changes",config.MapfixID,
|
action!("mapfixes",action_mapfix_request_changes,config,ActionMapfixRequestChangesRequest,"status/validator-request-changes",config.MapfixID.0,);
|
||||||
("ErrorMessage",config.ErrorMessage.as_str())
|
action!("mapfixes",action_mapfix_submitted,config,ActionMapfixSubmittedRequest,"status/validator-submitted",config.MapfixID.0,
|
||||||
);
|
|
||||||
action!("mapfixes",action_mapfix_submitted,config,ActionMapfixSubmittedRequest,"status/validator-submitted",config.MapfixID,
|
|
||||||
("ModelVersion",config.ModelVersion.to_string().as_str())
|
("ModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
("DisplayName",config.DisplayName.as_str())
|
("DisplayName",config.DisplayName.as_str())
|
||||||
("Creator",config.Creator.as_str())
|
("Creator",config.Creator.as_str())
|
||||||
("GameID",config.GameID.to_string().as_str())
|
("GameID",(config.GameID as u8).to_string().as_str())
|
||||||
);
|
);
|
||||||
action!("mapfixes",action_mapfix_validated,config,MapfixID,"status/validator-validated",config.0,);
|
action!("mapfixes",action_mapfix_validated,config,MapfixID,"status/validator-validated",config.0,);
|
||||||
action!("mapfixes",update_mapfix_validated_model,config,UpdateMapfixModelRequest,"validated-model",config.MapfixID,
|
action!("mapfixes",update_mapfix_validated_model,config,UpdateMapfixModelRequest,"validated-model",config.MapfixID.0,
|
||||||
("ValidatedModelID",config.ModelID.to_string().as_str())
|
("ValidatedModelID",config.ModelID.to_string().as_str())
|
||||||
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
);
|
);
|
||||||
action!("mapfixes",action_mapfix_uploaded,config,ActionMapfixUploadedRequest,"status/validator-uploaded",config.MapfixID,);
|
action!("mapfixes",action_mapfix_uploaded,config,ActionMapfixUploadedRequest,"status/validator-uploaded",config.MapfixID.0,);
|
||||||
action!("mapfixes",action_mapfix_accepted,config,ActionMapfixAcceptedRequest,"status/validator-failed",config.MapfixID,
|
action!("mapfixes",action_mapfix_accepted,config,ActionMapfixAcceptedRequest,"status/validator-failed",config.MapfixID.0,);
|
||||||
("ErrorMessage",config.ErrorMessage.as_str())
|
|
||||||
);
|
|
||||||
// simple operation endpoint
|
// simple operation endpoint
|
||||||
action!("operations",action_operation_failed,config,ActionOperationFailedRequest,"status/operation-failed",config.OperationID,
|
action!("operations",action_operation_failed,config,ActionOperationFailedRequest,"status/operation-failed",config.OperationID.0,
|
||||||
("StatusMessage",config.StatusMessage.as_str())
|
("StatusMessage",config.StatusMessage.as_str())
|
||||||
);
|
);
|
||||||
|
action!("mapfixes",create_mapfix_audit_error,config,CreateMapfixAuditErrorRequest,"error",config.MapfixID.0,
|
||||||
|
("ErrorMessage",config.ErrorMessage.as_str())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,21 @@ impl std::fmt::Display for Error{
|
|||||||
impl std::error::Error for Error{}
|
impl std::error::Error for Error{}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SingleItemError{
|
pub enum SingleItemError<Items>{
|
||||||
DuplicateItems,
|
DuplicateItems(Items),
|
||||||
Other(Error),
|
Other(Error),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for SingleItemError{
|
impl<Items> std::fmt::Display for SingleItemError<Items>
|
||||||
|
where
|
||||||
|
Items:std::fmt::Debug
|
||||||
|
{
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
write!(f,"{self:?}")
|
write!(f,"{self:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::error::Error for SingleItemError{}
|
impl<Items> std::error::Error for SingleItemError<Items> where Items:std::fmt::Debug{}
|
||||||
|
pub type ScriptSingleItemError=SingleItemError<Vec<ScriptID>>;
|
||||||
|
pub type ScriptPolicySingleItemError=SingleItemError<Vec<ScriptPolicyID>>;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -62,15 +67,23 @@ pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,Ord,PartialOrd,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum GameID{
|
||||||
|
Bhop=1,
|
||||||
|
Surf=2,
|
||||||
|
KreedzClimb=3,
|
||||||
|
FlyTrials=5,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct CreateMapfixRequest<'a>{
|
pub struct CreateMapfixRequest<'a>{
|
||||||
pub OperationID:i32,
|
pub OperationID:OperationID,
|
||||||
pub AssetOwner:i64,
|
pub AssetOwner:i64,
|
||||||
pub DisplayName:&'a str,
|
pub DisplayName:&'a str,
|
||||||
pub Creator:&'a str,
|
pub Creator:&'a str,
|
||||||
pub GameID:i32,
|
pub GameID:GameID,
|
||||||
pub AssetID:u64,
|
pub AssetID:u64,
|
||||||
pub AssetVersion:u64,
|
pub AssetVersion:u64,
|
||||||
pub TargetAssetID:u64,
|
pub TargetAssetID:u64,
|
||||||
@@ -85,11 +98,11 @@ pub struct MapfixIDResponse{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct CreateSubmissionRequest<'a>{
|
pub struct CreateSubmissionRequest<'a>{
|
||||||
pub OperationID:i32,
|
pub OperationID:OperationID,
|
||||||
pub AssetOwner:i64,
|
pub AssetOwner:i64,
|
||||||
pub DisplayName:&'a str,
|
pub DisplayName:&'a str,
|
||||||
pub Creator:&'a str,
|
pub Creator:&'a str,
|
||||||
pub GameID:i32,
|
pub GameID:GameID,
|
||||||
pub AssetID:u64,
|
pub AssetID:u64,
|
||||||
pub AssetVersion:u64,
|
pub AssetVersion:u64,
|
||||||
pub Status:u32,
|
pub Status:u32,
|
||||||
@@ -132,7 +145,7 @@ pub struct GetScriptsRequest<'a>{
|
|||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub ResourceType:Option<ResourceType>,
|
pub ResourceType:Option<ResourceType>,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub ResourceID:Option<i64>,
|
pub ResourceID:Option<ResourceID>,
|
||||||
}
|
}
|
||||||
#[derive(Clone,Copy,Debug)]
|
#[derive(Clone,Copy,Debug)]
|
||||||
pub struct HashRequest<'a>{
|
pub struct HashRequest<'a>{
|
||||||
@@ -146,7 +159,7 @@ pub struct ScriptResponse{
|
|||||||
pub Hash:String,
|
pub Hash:String,
|
||||||
pub Source:String,
|
pub Source:String,
|
||||||
pub ResourceType:ResourceType,
|
pub ResourceType:ResourceType,
|
||||||
pub ResourceID:i64,
|
pub ResourceID:ResourceID,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
@@ -155,7 +168,7 @@ pub struct CreateScriptRequest<'a>{
|
|||||||
pub Source:&'a str,
|
pub Source:&'a str,
|
||||||
pub ResourceType:ResourceType,
|
pub ResourceType:ResourceType,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub ResourceID:Option<i64>,
|
pub ResourceID:Option<ResourceID>,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
@@ -225,49 +238,160 @@ pub struct UpdateScriptPolicyRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct UpdateSubmissionModelRequest{
|
pub struct UpdateSubmissionModelRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub enum Sort{
|
||||||
|
Disabled=0,
|
||||||
|
DisplayNameAscending=1,
|
||||||
|
DisplayNameDescending=2,
|
||||||
|
DateAscending=3,
|
||||||
|
DateDescending=4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug,serde_repr::Deserialize_repr)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum SubmissionStatus{
|
||||||
|
// Phase: Creation
|
||||||
|
UnderConstruction=0,
|
||||||
|
ChangesRequested=1,
|
||||||
|
|
||||||
|
// Phase: Review
|
||||||
|
Submitting=2,
|
||||||
|
Submitted=3,
|
||||||
|
|
||||||
|
// Phase: Testing
|
||||||
|
AcceptedUnvalidated=4, // pending script review, can re-trigger validation
|
||||||
|
Validating=5,
|
||||||
|
Validated=6,
|
||||||
|
Uploading=7,
|
||||||
|
Uploaded=8, // uploaded to the group, but pending release
|
||||||
|
|
||||||
|
// Phase: Final SubmissionStatus
|
||||||
|
Rejected=9,
|
||||||
|
Released=10,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct GetSubmissionsRequest<'a>{
|
||||||
|
pub Page:u32,
|
||||||
|
pub Limit:u32,
|
||||||
|
pub Sort:Option<Sort>,
|
||||||
|
pub DisplayName:Option<&'a str>,
|
||||||
|
pub Creator:Option<&'a str>,
|
||||||
|
pub GameID:Option<GameID>,
|
||||||
|
pub Submitter:Option<u64>,
|
||||||
|
pub AssetID:Option<u64>,
|
||||||
|
pub UploadedAssetID:Option<u64>,
|
||||||
|
pub StatusID:Option<SubmissionStatus>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
|
pub struct SubmissionResponse{
|
||||||
|
pub ID:SubmissionID,
|
||||||
|
pub DisplayName:String,
|
||||||
|
pub Creator:String,
|
||||||
|
pub GameID:GameID,
|
||||||
|
pub CreatedAt:i64,
|
||||||
|
pub UpdatedAt:i64,
|
||||||
|
pub Submitter:u64,
|
||||||
|
pub AssetID:u64,
|
||||||
|
pub AssetVersion:u64,
|
||||||
|
pub UploadedAssetID:u64,
|
||||||
|
pub StatusID:SubmissionStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
|
pub struct SubmissionsResponse{
|
||||||
|
pub Total:u64,
|
||||||
|
pub Submissions:Vec<SubmissionResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct GetMapsRequest<'a>{
|
||||||
|
pub Page:u32,
|
||||||
|
pub Limit:u32,
|
||||||
|
pub Sort:Option<Sort>,
|
||||||
|
pub DisplayName:Option<&'a str>,
|
||||||
|
pub Creator:Option<&'a str>,
|
||||||
|
pub GameID:Option<GameID>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
|
pub struct MapResponse{
|
||||||
|
pub ID:i64,
|
||||||
|
pub DisplayName:String,
|
||||||
|
pub Creator:String,
|
||||||
|
pub GameID:GameID,
|
||||||
|
pub Date:i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
|
pub struct Check{
|
||||||
|
pub Name:&'static str,
|
||||||
|
pub Summary:String,
|
||||||
|
pub Passed:bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionSubmittedRequest{
|
pub struct ActionSubmissionSubmittedRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub DisplayName:String,
|
pub DisplayName:String,
|
||||||
pub Creator:String,
|
pub Creator:String,
|
||||||
pub GameID:u32,
|
pub GameID:GameID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionRequestChangesRequest{
|
pub struct ActionSubmissionRequestChangesRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub ErrorMessage:String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionUploadedRequest{
|
pub struct ActionSubmissionUploadedRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub UploadedAssetID:u64,
|
pub UploadedAssetID:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionAcceptedRequest{
|
pub struct ActionSubmissionAcceptedRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct CreateSubmissionAuditErrorRequest{
|
||||||
|
pub SubmissionID:SubmissionID,
|
||||||
pub ErrorMessage:String,
|
pub ErrorMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,serde::Deserialize)]
|
#[allow(nonstandard_style)]
|
||||||
pub struct SubmissionID(pub i64);
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct CreateSubmissionAuditCheckListRequest<'a>{
|
||||||
|
pub SubmissionID:SubmissionID,
|
||||||
|
pub CheckList:&'a [Check],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
|
pub struct SubmissionID(pub(crate)i64);
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct UpdateMapfixModelRequest{
|
pub struct UpdateMapfixModelRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
}
|
}
|
||||||
@@ -275,39 +399,82 @@ pub struct UpdateMapfixModelRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixSubmittedRequest{
|
pub struct ActionMapfixSubmittedRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub DisplayName:String,
|
pub DisplayName:String,
|
||||||
pub Creator:String,
|
pub Creator:String,
|
||||||
pub GameID:u32,
|
pub GameID:GameID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixRequestChangesRequest{
|
pub struct ActionMapfixRequestChangesRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ErrorMessage:String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixUploadedRequest{
|
pub struct ActionMapfixUploadedRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixAcceptedRequest{
|
pub struct ActionMapfixAcceptedRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct CreateMapfixAuditErrorRequest{
|
||||||
|
pub MapfixID:MapfixID,
|
||||||
pub ErrorMessage:String,
|
pub ErrorMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,serde::Deserialize)]
|
#[allow(nonstandard_style)]
|
||||||
pub struct MapfixID(pub i64);
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct CreateMapfixAuditCheckListRequest<'a>{
|
||||||
|
pub MapfixID:MapfixID,
|
||||||
|
pub CheckList:&'a [Check],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
|
pub struct MapfixID(pub(crate)i64);
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionOperationFailedRequest{
|
pub struct ActionOperationFailedRequest{
|
||||||
pub OperationID:i32,
|
pub OperationID:OperationID,
|
||||||
pub StatusMessage:String,
|
pub StatusMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
|
pub struct OperationID(pub(crate)i64);
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
|
pub struct ResourceID(pub(crate)i64);
|
||||||
|
|
||||||
|
#[derive(Clone,Copy,Debug)]
|
||||||
|
pub enum Resource{
|
||||||
|
Submission(SubmissionID),
|
||||||
|
Mapfix(MapfixID),
|
||||||
|
}
|
||||||
|
impl Resource{
|
||||||
|
pub fn split(self)->(ResourceType,ResourceID){
|
||||||
|
match self{
|
||||||
|
Resource::Mapfix(MapfixID(mapfix_id))=>(ResourceType::Mapfix,ResourceID(mapfix_id)),
|
||||||
|
Resource::Submission(SubmissionID(submission_id))=>(ResourceType::Submission,ResourceID(submission_id)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(nonstandard_style)]
|
||||||
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
|
pub struct ReleaseInfo{
|
||||||
|
pub SubmissionID:SubmissionID,
|
||||||
|
pub Date:chrono::DateTime<chrono::Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ReleaseRequest<'a>{
|
||||||
|
pub schedule:&'a [ReleaseInfo],
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use std::collections::{HashSet,HashMap};
|
use std::collections::{HashSet,HashMap};
|
||||||
use crate::download::download_asset_version;
|
use crate::download::download_asset_version;
|
||||||
use crate::rbx_util::{class_is_a,get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID,ParseGameIDError,MapInfo,GetRootInstanceError,StringValueError};
|
use crate::rbx_util::{get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID,ParseGameIDError,MapInfo,GetRootInstanceError,StringValueError};
|
||||||
|
|
||||||
use heck::{ToSnakeCase,ToTitleCase};
|
use heck::{ToSnakeCase,ToTitleCase};
|
||||||
|
use submissions_api::types::Check;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -12,6 +13,7 @@ pub enum Error{
|
|||||||
Download(crate::download::Error),
|
Download(crate::download::Error),
|
||||||
ModelFileDecode(ReadDomError),
|
ModelFileDecode(ReadDomError),
|
||||||
GetRootInstance(GetRootInstanceError),
|
GetRootInstance(GetRootInstanceError),
|
||||||
|
IntoMapInfoOwned(IntoMapInfoOwnedError),
|
||||||
ToJsonValue(serde_json::Error),
|
ToJsonValue(serde_json::Error),
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for Error{
|
impl std::fmt::Display for Error{
|
||||||
@@ -23,13 +25,15 @@ impl std::error::Error for Error{}
|
|||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
pub struct CheckRequest{
|
pub struct CheckRequest{
|
||||||
pub ModelID:u64,
|
ModelID:u64,
|
||||||
|
SkipChecks:bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crate::nats_types::CheckMapfixRequest> for CheckRequest{
|
impl From<crate::nats_types::CheckMapfixRequest> for CheckRequest{
|
||||||
fn from(value:crate::nats_types::CheckMapfixRequest)->Self{
|
fn from(value:crate::nats_types::CheckMapfixRequest)->Self{
|
||||||
Self{
|
Self{
|
||||||
ModelID:value.ModelID,
|
ModelID:value.ModelID,
|
||||||
|
SkipChecks:value.SkipChecks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,6 +41,7 @@ impl From<crate::nats_types::CheckSubmissionRequest> for CheckRequest{
|
|||||||
fn from(value:crate::nats_types::CheckSubmissionRequest)->Self{
|
fn from(value:crate::nats_types::CheckSubmissionRequest)->Self{
|
||||||
Self{
|
Self{
|
||||||
ModelID:value.ModelID,
|
ModelID:value.ModelID,
|
||||||
|
SkipChecks:value.SkipChecks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,27 +230,33 @@ pub fn get_model_info<'a>(dom:&'a rbx_dom_weak::WeakDom,model_instance:&'a rbx_d
|
|||||||
|
|
||||||
// count objects (default count is 0)
|
// count objects (default count is 0)
|
||||||
let mut counts=Counts::default();
|
let mut counts=Counts::default();
|
||||||
for instance in dom.descendants_of(model_instance.referent()){
|
|
||||||
if class_is_a(instance.class.as_str(),"BasePart"){
|
let db=rbx_reflection_database::get();
|
||||||
// Zones
|
let base_part=&db.classes["BasePart"];
|
||||||
match instance.name.parse(){
|
let base_parts=dom.descendants_of(model_instance.referent()).filter(|&instance|
|
||||||
Ok(ModeElement{zone:Zone::Start,mode_id})=>counts.mode_start_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
db.classes.get(instance.class.as_str()).is_some_and(|class|
|
||||||
Ok(ModeElement{zone:Zone::Finish,mode_id})=>counts.mode_finish_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
db.has_superclass(class,base_part)
|
||||||
Ok(ModeElement{zone:Zone::Anticheat,mode_id})=>counts.mode_anticheat_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
)
|
||||||
Err(_)=>(),
|
);
|
||||||
}
|
for instance in base_parts{
|
||||||
// Spawns & Teleports
|
// Zones
|
||||||
match instance.name.parse(){
|
match instance.name.parse(){
|
||||||
Ok(StageElement{behaviour:StageElementBehaviour::Teleport,stage_id})=>counts.teleport_counts.entry(stage_id).or_default().push(instance.name.as_str()),
|
Ok(ModeElement{zone:Zone::Start,mode_id})=>counts.mode_start_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
||||||
Ok(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id})=>*counts.spawn_counts.entry(stage_id).or_insert(0)+=1,
|
Ok(ModeElement{zone:Zone::Finish,mode_id})=>counts.mode_finish_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
||||||
Err(_)=>(),
|
Ok(ModeElement{zone:Zone::Anticheat,mode_id})=>counts.mode_anticheat_counts.entry(mode_id).or_default().push(instance.name.as_str()),
|
||||||
}
|
Err(_)=>(),
|
||||||
// Wormholes
|
}
|
||||||
match instance.name.parse(){
|
// Spawns & Teleports
|
||||||
Ok(WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id})=>*counts.wormhole_in_counts.entry(wormhole_id).or_insert(0)+=1,
|
match instance.name.parse(){
|
||||||
Ok(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id})=>*counts.wormhole_out_counts.entry(wormhole_id).or_insert(0)+=1,
|
Ok(StageElement{behaviour:StageElementBehaviour::Teleport,stage_id})=>counts.teleport_counts.entry(stage_id).or_default().push(instance.name.as_str()),
|
||||||
Err(_)=>(),
|
Ok(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id})=>*counts.spawn_counts.entry(stage_id).or_insert(0)+=1,
|
||||||
}
|
Err(_)=>(),
|
||||||
|
}
|
||||||
|
// Wormholes
|
||||||
|
match instance.name.parse(){
|
||||||
|
Ok(WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id})=>*counts.wormhole_in_counts.entry(wormhole_id).or_insert(0)+=1,
|
||||||
|
Ok(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id})=>*counts.wormhole_out_counts.entry(wormhole_id).or_insert(0)+=1,
|
||||||
|
Err(_)=>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,6 +387,23 @@ pub struct MapInfoOwned{
|
|||||||
pub creator:String,
|
pub creator:String,
|
||||||
pub game_id:GameID,
|
pub game_id:GameID,
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum IntoMapInfoOwnedError{
|
||||||
|
DisplayName(StringValueError),
|
||||||
|
Creator(StringValueError),
|
||||||
|
GameID(ParseGameIDError),
|
||||||
|
}
|
||||||
|
impl TryFrom<MapInfo<'_>> for MapInfoOwned{
|
||||||
|
type Error=IntoMapInfoOwnedError;
|
||||||
|
fn try_from(value:MapInfo<'_>)->Result<Self,Self::Error>{
|
||||||
|
Ok(Self{
|
||||||
|
display_name:value.display_name.map_err(IntoMapInfoOwnedError::DisplayName)?.to_owned(),
|
||||||
|
creator:value.creator.map_err(IntoMapInfoOwnedError::Creator)?.to_owned(),
|
||||||
|
game_id:value.game_id.map_err(IntoMapInfoOwnedError::GameID)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Named dummy types for readability
|
// Named dummy types for readability
|
||||||
struct Exists;
|
struct Exists;
|
||||||
@@ -585,40 +613,31 @@ impl<D:std::fmt::Display> std::fmt::Display for Duplicates<D>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
|
||||||
struct CheckSummary{
|
macro_rules! passed{
|
||||||
name:&'static str,
|
($name:literal)=>{
|
||||||
summary:String,
|
Check{
|
||||||
passed:bool,
|
Name:$name,
|
||||||
details:serde_json::Value,
|
Summary:String::new(),
|
||||||
}
|
Passed:true,
|
||||||
impl CheckSummary{
|
|
||||||
const fn passed(name:&'static str)->Self{
|
|
||||||
Self{
|
|
||||||
name,
|
|
||||||
summary:String::new(),
|
|
||||||
passed:true,
|
|
||||||
details:serde_json::Value::Null,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
macro_rules! summary{
|
macro_rules! summary{
|
||||||
($name:literal,$summary:expr,$details:expr)=>{
|
($name:literal,$summary:expr)=>{
|
||||||
CheckSummary{
|
Check{
|
||||||
name:$name,
|
Name:$name,
|
||||||
summary:$summary,
|
Summary:$summary,
|
||||||
passed:false,
|
Passed:false,
|
||||||
details:serde_json::to_value($details)?,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
macro_rules! summary_format{
|
macro_rules! summary_format{
|
||||||
($name:literal,$fmt:literal,$details:expr)=>{
|
($name:literal,$fmt:literal)=>{
|
||||||
CheckSummary{
|
Check{
|
||||||
name:$name,
|
Name:$name,
|
||||||
summary:format!($fmt),
|
Summary:format!($fmt),
|
||||||
passed:false,
|
Passed:false,
|
||||||
details:serde_json::to_value($details)?,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -628,134 +647,134 @@ macro_rules! summary_format{
|
|||||||
impl MapCheck<'_>{
|
impl MapCheck<'_>{
|
||||||
fn itemize(&self)->Result<MapCheckList,serde_json::Error>{
|
fn itemize(&self)->Result<MapCheckList,serde_json::Error>{
|
||||||
let model_class=match &self.model_class{
|
let model_class=match &self.model_class{
|
||||||
StringCheck(Ok(()))=>CheckSummary::passed("ModelClass"),
|
StringCheck(Ok(()))=>passed!("ModelClass"),
|
||||||
StringCheck(Err(context))=>summary_format!("ModelClass","Invalid model class: {context}",()),
|
StringCheck(Err(context))=>summary_format!("ModelClass","Invalid model class: {context}"),
|
||||||
};
|
};
|
||||||
let model_name=match &self.model_name{
|
let model_name=match &self.model_name{
|
||||||
StringCheck(Ok(()))=>CheckSummary::passed("ModelName"),
|
StringCheck(Ok(()))=>passed!("ModelName"),
|
||||||
StringCheck(Err(context))=>summary_format!("ModelName","Model name must have snake_case: {context}",()),
|
StringCheck(Err(context))=>summary_format!("ModelName","Model name must have snake_case: {context}"),
|
||||||
};
|
};
|
||||||
let display_name=match &self.display_name{
|
let display_name=match &self.display_name{
|
||||||
Ok(Ok(StringCheck(Ok(_))))=>CheckSummary::passed("DisplayName"),
|
Ok(Ok(StringCheck(Ok(_))))=>passed!("DisplayName"),
|
||||||
Ok(Ok(StringCheck(Err(context))))=>summary_format!("DisplayName","DisplayName must have Title Case: {context}",()),
|
Ok(Ok(StringCheck(Err(context))))=>summary_format!("DisplayName","DisplayName must have Title Case: {context}"),
|
||||||
Ok(Err(context))=>summary_format!("DisplayName","Invalid DisplayName: {context}",()),
|
Ok(Err(context))=>summary_format!("DisplayName","Invalid DisplayName: {context}"),
|
||||||
Err(StringValueError::ObjectNotFound)=>summary!("DisplayName","Missing DisplayName StringValue".to_owned(),()),
|
Err(StringValueError::ObjectNotFound)=>summary!("DisplayName","Missing DisplayName StringValue".to_owned()),
|
||||||
Err(StringValueError::ValueNotSet)=>summary!("DisplayName","DisplayName Value not set".to_owned(),()),
|
Err(StringValueError::ValueNotSet)=>summary!("DisplayName","DisplayName Value not set".to_owned()),
|
||||||
Err(StringValueError::NonStringValue)=>summary!("DisplayName","DisplayName Value is not a String".to_owned(),()),
|
Err(StringValueError::NonStringValue)=>summary!("DisplayName","DisplayName Value is not a String".to_owned()),
|
||||||
};
|
};
|
||||||
let creator=match &self.creator{
|
let creator=match &self.creator{
|
||||||
Ok(Ok(_))=>CheckSummary::passed("Creator"),
|
Ok(Ok(_))=>passed!("Creator"),
|
||||||
Ok(Err(context))=>summary_format!("Creator","Invalid Creator: {context}",()),
|
Ok(Err(context))=>summary_format!("Creator","Invalid Creator: {context}"),
|
||||||
Err(StringValueError::ObjectNotFound)=>summary!("Creator","Missing Creator StringValue".to_owned(),()),
|
Err(StringValueError::ObjectNotFound)=>summary!("Creator","Missing Creator StringValue".to_owned()),
|
||||||
Err(StringValueError::ValueNotSet)=>summary!("Creator","Creator Value not set".to_owned(),()),
|
Err(StringValueError::ValueNotSet)=>summary!("Creator","Creator Value not set".to_owned()),
|
||||||
Err(StringValueError::NonStringValue)=>summary!("Creator","Creator Value is not a String".to_owned(),()),
|
Err(StringValueError::NonStringValue)=>summary!("Creator","Creator Value is not a String".to_owned()),
|
||||||
};
|
};
|
||||||
let game_id=match &self.game_id{
|
let game_id=match &self.game_id{
|
||||||
Ok(_)=>CheckSummary::passed("GameID"),
|
Ok(_)=>passed!("GameID"),
|
||||||
Err(ParseGameIDError)=>summary!("GameID","Model name must be prefixed with bhop_ surf_ or flytrials_".to_owned(),()),
|
Err(ParseGameIDError)=>summary!("GameID","Model name must be prefixed with bhop_ surf_ or flytrials_".to_owned()),
|
||||||
};
|
};
|
||||||
let mapstart=match &self.mapstart{
|
let mapstart=match &self.mapstart{
|
||||||
Ok(Exists)=>CheckSummary::passed("MapStart"),
|
Ok(Exists)=>passed!("MapStart"),
|
||||||
Err(Absent)=>summary_format!("MapStart","Model has no MapStart",()),
|
Err(Absent)=>summary_format!("MapStart","Model has no MapStart"),
|
||||||
};
|
};
|
||||||
let duplicate_start=match &self.mode_start_counts{
|
let duplicate_start=match &self.mode_start_counts{
|
||||||
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateStart"),
|
DuplicateCheck(Ok(()))=>passed!("DuplicateStart"),
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&mode_id,names)|
|
let context=Separated::new(", ",||context.iter().map(|(&mode_id,names)|
|
||||||
Duplicates::new(ModeElement{zone:Zone::Start,mode_id},names.len())
|
Duplicates::new(ModeElement{zone:Zone::Start,mode_id},names.len())
|
||||||
));
|
));
|
||||||
summary_format!("DuplicateStart","Duplicate start zones: {context}",())
|
summary_format!("DuplicateStart","Duplicate start zones: {context}")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let (extra_finish,missing_finish)=match &self.mode_finish_counts{
|
let (extra_finish,missing_finish)=match &self.mode_finish_counts{
|
||||||
SetDifferenceCheck(Ok(()))=>(CheckSummary::passed("ExtraFinish"),CheckSummary::passed("MissingFinish")),
|
SetDifferenceCheck(Ok(()))=>(passed!("DanglingFinish"),passed!("MissingFinish")),
|
||||||
SetDifferenceCheck(Err(context))=>(
|
SetDifferenceCheck(Err(context))=>(
|
||||||
if context.extra.is_empty(){
|
if context.extra.is_empty(){
|
||||||
CheckSummary::passed("ExtraFinish")
|
passed!("DanglingFinish")
|
||||||
}else{
|
}else{
|
||||||
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
|
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
|
||||||
ModeElement{zone:Zone::Finish,mode_id}
|
ModeElement{zone:Zone::Finish,mode_id}
|
||||||
));
|
));
|
||||||
summary_format!("ExtraFinish","No matching start zone for finish {plural}: {context}",())
|
summary_format!("DanglingFinish","No matching start zone for finish {plural}: {context}")
|
||||||
},
|
},
|
||||||
if context.missing.is_empty(){
|
if context.missing.is_empty(){
|
||||||
CheckSummary::passed("MissingFinish")
|
passed!("MissingFinish")
|
||||||
}else{
|
}else{
|
||||||
let plural=if context.missing.len()==1{"zone"}else{"zones"};
|
let plural=if context.missing.len()==1{"zone"}else{"zones"};
|
||||||
let context=Separated::new(", ",||context.missing.iter().map(|&mode_id|
|
let context=Separated::new(", ",||context.missing.iter().map(|&mode_id|
|
||||||
ModeElement{zone:Zone::Finish,mode_id}
|
ModeElement{zone:Zone::Finish,mode_id}
|
||||||
));
|
));
|
||||||
summary_format!("MissingFinish","Missing finish {plural}: {context}",())
|
summary_format!("MissingFinish","Missing finish {plural}: {context}")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let dangling_anticheat=match &self.mode_anticheat_counts{
|
let dangling_anticheat=match &self.mode_anticheat_counts{
|
||||||
SetDifferenceCheck(Ok(()))=>CheckSummary::passed("DanglingAnticheat"),
|
SetDifferenceCheck(Ok(()))=>passed!("DanglingAnticheat"),
|
||||||
SetDifferenceCheck(Err(context))=>{
|
SetDifferenceCheck(Err(context))=>{
|
||||||
if context.extra.is_empty(){
|
if context.extra.is_empty(){
|
||||||
CheckSummary::passed("DanglingAnticheat")
|
passed!("DanglingAnticheat")
|
||||||
}else{
|
}else{
|
||||||
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
|
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_names)|
|
||||||
ModeElement{zone:Zone::Anticheat,mode_id}
|
ModeElement{zone:Zone::Anticheat,mode_id}
|
||||||
));
|
));
|
||||||
summary_format!("DanglingAnticheat","No matching start zone for anticheat {plural}: {context}",())
|
summary_format!("DanglingAnticheat","No matching start zone for anticheat {plural}: {context}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let spawn1=match &self.spawn1{
|
let spawn1=match &self.spawn1{
|
||||||
Ok(Exists)=>CheckSummary::passed("Spawn1"),
|
Ok(Exists)=>passed!("Spawn1"),
|
||||||
Err(Absent)=>summary_format!("Spawn1","Model has no Spawn1",()),
|
Err(Absent)=>summary_format!("Spawn1","Model has no Spawn1"),
|
||||||
};
|
};
|
||||||
let dangling_teleport=match &self.teleport_counts{
|
let dangling_teleport=match &self.teleport_counts{
|
||||||
SetDifferenceCheck(Ok(()))=>CheckSummary::passed("DanglingTeleport"),
|
SetDifferenceCheck(Ok(()))=>passed!("DanglingTeleport"),
|
||||||
SetDifferenceCheck(Err(context))=>{
|
SetDifferenceCheck(Err(context))=>{
|
||||||
let unique_names:HashSet<_>=context.extra.values().flat_map(|names|names.iter().copied()).collect();
|
let unique_names:HashSet<_>=context.extra.values().flat_map(|names|names.iter().copied()).collect();
|
||||||
let plural=if unique_names.len()==1{"object"}else{"objects"};
|
let plural=if unique_names.len()==1{"object"}else{"objects"};
|
||||||
let context=Separated::new(", ",||&unique_names);
|
let context=Separated::new(", ",||&unique_names);
|
||||||
summary_format!("DanglingTeleport","No matching Spawn for {plural}: {context}",())
|
summary_format!("DanglingTeleport","No matching Spawn for {plural}: {context}")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let duplicate_spawns=match &self.spawn_counts{
|
let duplicate_spawns=match &self.spawn_counts{
|
||||||
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateSpawn"),
|
DuplicateCheck(Ok(()))=>passed!("DuplicateSpawn"),
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&stage_id,&names)|
|
let context=Separated::new(", ",||context.iter().map(|(&stage_id,&names)|
|
||||||
Duplicates::new(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id},names as usize)
|
Duplicates::new(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id},names as usize)
|
||||||
));
|
));
|
||||||
summary_format!("DuplicateSpawn","Duplicate Spawn: {context}",())
|
summary_format!("DuplicateSpawn","Duplicate Spawn: {context}")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let (extra_wormhole_in,missing_wormhole_in)=match &self.wormhole_in_counts{
|
let (extra_wormhole_in,missing_wormhole_in)=match &self.wormhole_in_counts{
|
||||||
SetDifferenceCheck(Ok(()))=>(CheckSummary::passed("ExtraWormholeIn"),CheckSummary::passed("MissingWormholeIn")),
|
SetDifferenceCheck(Ok(()))=>(passed!("ExtraWormholeIn"),passed!("MissingWormholeIn")),
|
||||||
SetDifferenceCheck(Err(context))=>(
|
SetDifferenceCheck(Err(context))=>(
|
||||||
if context.extra.is_empty(){
|
if context.extra.is_empty(){
|
||||||
CheckSummary::passed("ExtraWormholeIn")
|
passed!("ExtraWormholeIn")
|
||||||
}else{
|
}else{
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&wormhole_id,_names)|
|
let context=Separated::new(", ",||context.extra.iter().map(|(&wormhole_id,_names)|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id}
|
WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id}
|
||||||
));
|
));
|
||||||
summary_format!("ExtraWormholeIn","WormholeIn with no matching WormholeOut: {context}",())
|
summary_format!("ExtraWormholeIn","WormholeIn with no matching WormholeOut: {context}")
|
||||||
},
|
},
|
||||||
if context.missing.is_empty(){
|
if context.missing.is_empty(){
|
||||||
CheckSummary::passed("MissingWormholeIn")
|
passed!("MissingWormholeIn")
|
||||||
}else{
|
}else{
|
||||||
// This counts WormholeIn objects, but
|
// This counts WormholeIn objects, but
|
||||||
// flipped logic is easier to understand
|
// flipped logic is easier to understand
|
||||||
let context=Separated::new(", ",||context.missing.iter().map(|&wormhole_id|
|
let context=Separated::new(", ",||context.missing.iter().map(|&wormhole_id|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id}
|
WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id}
|
||||||
));
|
));
|
||||||
summary_format!("MissingWormholeIn","WormholeOut with no matching WormholeIn: {context}",())
|
summary_format!("MissingWormholeIn","WormholeOut with no matching WormholeIn: {context}")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let duplicate_wormhole_out=match &self.wormhole_out_counts{
|
let duplicate_wormhole_out=match &self.wormhole_out_counts{
|
||||||
DuplicateCheck(Ok(()))=>CheckSummary::passed("DuplicateWormholeOut"),
|
DuplicateCheck(Ok(()))=>passed!("DuplicateWormholeOut"),
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&wormhole_id,&names)|
|
let context=Separated::new(", ",||context.iter().map(|(&wormhole_id,&names)|
|
||||||
Duplicates::new(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id},names as usize)
|
Duplicates::new(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id},names as usize)
|
||||||
));
|
));
|
||||||
summary_format!("DuplicateWormholeOut","Duplicate WormholeOut: {context}",())
|
summary_format!("DuplicateWormholeOut","Duplicate WormholeOut: {context}")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(MapCheckList{checks:Box::new([
|
Ok(MapCheckList{checks:Box::new([
|
||||||
@@ -780,29 +799,17 @@ impl MapCheck<'_>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
struct MapCheckList{
|
pub struct MapCheckList{
|
||||||
checks:Box<[CheckSummary;16]>,
|
pub checks:Box<[Check;16]>,
|
||||||
}
|
|
||||||
impl MapCheckList{
|
|
||||||
fn summary(&self)->String{
|
|
||||||
Separated::new("; ",||self.checks.iter().filter_map(|check|
|
|
||||||
(!check.passed).then_some(check.summary.as_str())
|
|
||||||
)).to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Summary{
|
pub struct CheckListAndVersion{
|
||||||
pub summary:String,
|
pub status:Result<MapInfoOwned,MapCheckList>,
|
||||||
pub json:serde_json::Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CheckReportAndVersion{
|
|
||||||
pub status:Result<MapInfoOwned,Summary>,
|
|
||||||
pub version:u64,
|
pub version:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::message_handler::MessageHandler{
|
impl crate::message_handler::MessageHandler{
|
||||||
pub async fn check_inner(&self,check_info:CheckRequest)->Result<CheckReportAndVersion,Error>{
|
pub async fn check_inner(&self,check_info:CheckRequest)->Result<CheckListAndVersion,Error>{
|
||||||
// discover asset creator and latest version
|
// discover asset creator and latest version
|
||||||
let info=self.cloud_context.get_asset_info(
|
let info=self.cloud_context.get_asset_info(
|
||||||
rbx_asset::cloud::GetAssetLatestRequest{asset_id:check_info.ModelID}
|
rbx_asset::cloud::GetAssetLatestRequest{asset_id:check_info.ModelID}
|
||||||
@@ -827,6 +834,17 @@ impl crate::message_handler::MessageHandler{
|
|||||||
// extract the root instance
|
// extract the root instance
|
||||||
let model_instance=get_root_instance(&dom).map_err(Error::GetRootInstance)?;
|
let model_instance=get_root_instance(&dom).map_err(Error::GetRootInstance)?;
|
||||||
|
|
||||||
|
// skip checks
|
||||||
|
if check_info.SkipChecks{
|
||||||
|
// extract required fields
|
||||||
|
let map_info=get_mapinfo(&dom,model_instance);
|
||||||
|
let map_info_owned=map_info.try_into().map_err(Error::IntoMapInfoOwned)?;
|
||||||
|
let status=Ok(map_info_owned);
|
||||||
|
|
||||||
|
// return early
|
||||||
|
return Ok(CheckListAndVersion{status,version});
|
||||||
|
}
|
||||||
|
|
||||||
// extract information from the model
|
// extract information from the model
|
||||||
let model_info=get_model_info(&dom,model_instance);
|
let model_info=get_model_info(&dom,model_instance);
|
||||||
|
|
||||||
@@ -836,13 +854,10 @@ impl crate::message_handler::MessageHandler{
|
|||||||
// check the report, generate an error message if it fails the check
|
// check the report, generate an error message if it fails the check
|
||||||
let status=match map_check.result(){
|
let status=match map_check.result(){
|
||||||
Ok(map_info)=>Ok(map_info),
|
Ok(map_info)=>Ok(map_info),
|
||||||
Err(Ok(summary))=>Err(Summary{
|
Err(Ok(check_list))=>Err(check_list),
|
||||||
summary:summary.summary(),
|
|
||||||
json:serde_json::to_value(&summary).map_err(Error::ToJsonValue)?,
|
|
||||||
}),
|
|
||||||
Err(Err(e))=>return Err(Error::ToJsonValue(e)),
|
Err(Err(e))=>return Err(Error::ToJsonValue(e)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(CheckReportAndVersion{status,version})
|
Ok(CheckListAndVersion{status,version})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::check::CheckReportAndVersion;
|
use crate::check::CheckListAndVersion;
|
||||||
use crate::nats_types::CheckMapfixRequest;
|
use crate::nats_types::CheckMapfixRequest;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -21,20 +21,25 @@ impl crate::message_handler::MessageHandler{
|
|||||||
|
|
||||||
// update the mapfix depending on the result
|
// update the mapfix depending on the result
|
||||||
match check_result{
|
match check_result{
|
||||||
Ok(CheckReportAndVersion{status:Ok(map_info),version})=>self.api.action_mapfix_submitted(
|
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
|
||||||
submissions_api::types::ActionMapfixSubmittedRequest{
|
self.api.action_mapfix_submitted(
|
||||||
MapfixID:mapfix_id,
|
submissions_api::types::ActionMapfixSubmittedRequest{
|
||||||
ModelVersion:version,
|
MapfixID:mapfix_id,
|
||||||
DisplayName:map_info.display_name,
|
ModelVersion:version,
|
||||||
Creator:map_info.creator,
|
DisplayName:map_info.display_name,
|
||||||
GameID:map_info.game_id as u32,
|
Creator:map_info.creator,
|
||||||
}
|
GameID:map_info.game_id.into(),
|
||||||
).await.map_err(Error::ApiActionMapfixCheck)?,
|
}
|
||||||
|
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||||
|
|
||||||
|
// Do not proceed to request changes
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
// update the mapfix model status to request changes
|
// update the mapfix model status to request changes
|
||||||
Ok(CheckReportAndVersion{status:Err(report),..})=>self.api.action_mapfix_request_changes(
|
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_mapfix_audit_check_list(
|
||||||
submissions_api::types::ActionMapfixRequestChangesRequest{
|
submissions_api::types::CreateMapfixAuditCheckListRequest{
|
||||||
MapfixID:mapfix_id,
|
MapfixID:mapfix_id,
|
||||||
ErrorMessage:report.summary,
|
CheckList:check_list.checks.as_slice(),
|
||||||
}
|
}
|
||||||
).await.map_err(Error::ApiActionMapfixCheck)?,
|
).await.map_err(Error::ApiActionMapfixCheck)?,
|
||||||
// update the mapfix model status to request changes
|
// update the mapfix model status to request changes
|
||||||
@@ -42,8 +47,8 @@ impl crate::message_handler::MessageHandler{
|
|||||||
// log error
|
// log error
|
||||||
println!("[check_mapfix] Error: {e}");
|
println!("[check_mapfix] Error: {e}");
|
||||||
|
|
||||||
self.api.action_mapfix_request_changes(
|
self.api.create_mapfix_audit_error(
|
||||||
submissions_api::types::ActionMapfixRequestChangesRequest{
|
submissions_api::types::CreateMapfixAuditErrorRequest{
|
||||||
MapfixID:mapfix_id,
|
MapfixID:mapfix_id,
|
||||||
ErrorMessage:e.to_string(),
|
ErrorMessage:e.to_string(),
|
||||||
}
|
}
|
||||||
@@ -51,6 +56,12 @@ impl crate::message_handler::MessageHandler{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.api.action_mapfix_request_changes(
|
||||||
|
submissions_api::types::ActionMapfixRequestChangesRequest{
|
||||||
|
MapfixID:mapfix_id,
|
||||||
|
}
|
||||||
|
).await.map_err(Error::ApiActionMapfixCheck)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::check::CheckReportAndVersion;
|
use crate::check::CheckListAndVersion;
|
||||||
use crate::nats_types::CheckSubmissionRequest;
|
use crate::nats_types::CheckSubmissionRequest;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -22,20 +22,25 @@ impl crate::message_handler::MessageHandler{
|
|||||||
// update the submission depending on the result
|
// update the submission depending on the result
|
||||||
match check_result{
|
match check_result{
|
||||||
// update the submission model status to submitted
|
// update the submission model status to submitted
|
||||||
Ok(CheckReportAndVersion{status:Ok(map_info),version})=>self.api.action_submission_submitted(
|
Ok(CheckListAndVersion{status:Ok(map_info),version})=>{
|
||||||
submissions_api::types::ActionSubmissionSubmittedRequest{
|
self.api.action_submission_submitted(
|
||||||
SubmissionID:submission_id,
|
submissions_api::types::ActionSubmissionSubmittedRequest{
|
||||||
ModelVersion:version,
|
SubmissionID:submission_id,
|
||||||
DisplayName:map_info.display_name,
|
ModelVersion:version,
|
||||||
Creator:map_info.creator,
|
DisplayName:map_info.display_name,
|
||||||
GameID:map_info.game_id as u32,
|
Creator:map_info.creator,
|
||||||
}
|
GameID:map_info.game_id.into(),
|
||||||
).await.map_err(Error::ApiActionSubmissionCheck)?,
|
}
|
||||||
|
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||||
|
|
||||||
|
// Do not proceed to request changes
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
// update the submission model status to request changes
|
// update the submission model status to request changes
|
||||||
Ok(CheckReportAndVersion{status:Err(report),..})=>self.api.action_submission_request_changes(
|
Ok(CheckListAndVersion{status:Err(check_list),..})=>self.api.create_submission_audit_check_list(
|
||||||
submissions_api::types::ActionSubmissionRequestChangesRequest{
|
submissions_api::types::CreateSubmissionAuditCheckListRequest{
|
||||||
SubmissionID:submission_id,
|
SubmissionID:submission_id,
|
||||||
ErrorMessage:report.summary,
|
CheckList:check_list.checks.as_slice(),
|
||||||
}
|
}
|
||||||
).await.map_err(Error::ApiActionSubmissionCheck)?,
|
).await.map_err(Error::ApiActionSubmissionCheck)?,
|
||||||
// update the submission model status to request changes
|
// update the submission model status to request changes
|
||||||
@@ -43,8 +48,8 @@ impl crate::message_handler::MessageHandler{
|
|||||||
// log error
|
// log error
|
||||||
println!("[check_submission] Error: {e}");
|
println!("[check_submission] Error: {e}");
|
||||||
|
|
||||||
self.api.action_submission_request_changes(
|
self.api.create_submission_audit_error(
|
||||||
submissions_api::types::ActionSubmissionRequestChangesRequest{
|
submissions_api::types::CreateSubmissionAuditErrorRequest{
|
||||||
SubmissionID:submission_id,
|
SubmissionID:submission_id,
|
||||||
ErrorMessage:e.to_string(),
|
ErrorMessage:e.to_string(),
|
||||||
}
|
}
|
||||||
@@ -52,6 +57,12 @@ impl crate::message_handler::MessageHandler{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.api.action_submission_request_changes(
|
||||||
|
submissions_api::types::ActionSubmissionRequestChangesRequest{
|
||||||
|
SubmissionID:submission_id,
|
||||||
|
}
|
||||||
|
).await.map_err(Error::ApiActionSubmissionCheck)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ impl crate::message_handler::MessageHandler{
|
|||||||
DisplayName:create_request.DisplayName.as_deref().unwrap_or_default(),
|
DisplayName:create_request.DisplayName.as_deref().unwrap_or_default(),
|
||||||
Creator:create_request.Creator.as_deref().unwrap_or_default(),
|
Creator:create_request.Creator.as_deref().unwrap_or_default(),
|
||||||
// not great TODO: make this great
|
// not great TODO: make this great
|
||||||
GameID:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop) as i32,
|
GameID:create_request.GameID.unwrap_or(crate::rbx_util::GameID::Bhop).into(),
|
||||||
AssetID:create_info.ModelID,
|
AssetID:create_info.ModelID,
|
||||||
AssetVersion:create_request.AssetVersion,
|
AssetVersion:create_request.AssetVersion,
|
||||||
TargetAssetID:create_info.TargetAssetID,
|
TargetAssetID:create_info.TargetAssetID,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ impl crate::message_handler::MessageHandler{
|
|||||||
AssetOwner:create_request.AssetOwner as i64,
|
AssetOwner:create_request.AssetOwner as i64,
|
||||||
DisplayName:display_name,
|
DisplayName:display_name,
|
||||||
Creator:creator,
|
Creator:creator,
|
||||||
GameID:game_id as i32,
|
GameID:game_id.into(),
|
||||||
AssetID:create_info.ModelID,
|
AssetID:create_info.ModelID,
|
||||||
AssetVersion:create_request.AssetVersion,
|
AssetVersion:create_request.AssetVersion,
|
||||||
Status:create_info.Status,
|
Status:create_info.Status,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use futures::StreamExt;
|
|||||||
mod rbx_util;
|
mod rbx_util;
|
||||||
mod message_handler;
|
mod message_handler;
|
||||||
mod nats_types;
|
mod nats_types;
|
||||||
mod types;
|
|
||||||
mod download;
|
mod download;
|
||||||
mod check;
|
mod check;
|
||||||
mod check_mapfix;
|
mod check_mapfix;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use submissions_api::types::{SubmissionID,MapfixID,OperationID};
|
||||||
|
|
||||||
// These represent the information needed in the nats message
|
// These represent the information needed in the nats message
|
||||||
// to perform the operation, not necessarily the over-the-wire format
|
// to perform the operation, not necessarily the over-the-wire format
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@
|
|||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct CreateSubmissionRequest{
|
pub struct CreateSubmissionRequest{
|
||||||
// operation_id is passed back in the response message
|
// operation_id is passed back in the response message
|
||||||
pub OperationID:i32,
|
pub OperationID:OperationID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub DisplayName:String,
|
pub DisplayName:String,
|
||||||
pub Creator:String,
|
pub Creator:String,
|
||||||
@@ -21,7 +23,7 @@ pub struct CreateSubmissionRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct CreateMapfixRequest{
|
pub struct CreateMapfixRequest{
|
||||||
pub OperationID:i32,
|
pub OperationID:OperationID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub TargetAssetID:u64,
|
pub TargetAssetID:u64,
|
||||||
pub Description:String,
|
pub Description:String,
|
||||||
@@ -30,22 +32,24 @@ pub struct CreateMapfixRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct CheckSubmissionRequest{
|
pub struct CheckSubmissionRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
|
pub SkipChecks:bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct CheckMapfixRequest{
|
pub struct CheckMapfixRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
|
pub SkipChecks:bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct ValidateSubmissionRequest{
|
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:SubmissionID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub ValidatedModelID:Option<u64>,
|
pub ValidatedModelID:Option<u64>,
|
||||||
@@ -55,7 +59,7 @@ pub struct ValidateSubmissionRequest{
|
|||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct ValidateMapfixRequest{
|
pub struct ValidateMapfixRequest{
|
||||||
// submission_id is passed back in the response message
|
// submission_id is passed back in the response message
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub ValidatedModelID:Option<u64>,
|
pub ValidatedModelID:Option<u64>,
|
||||||
@@ -65,7 +69,7 @@ pub struct ValidateMapfixRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct UploadSubmissionRequest{
|
pub struct UploadSubmissionRequest{
|
||||||
pub SubmissionID:i64,
|
pub SubmissionID:SubmissionID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub ModelName:String,
|
pub ModelName:String,
|
||||||
@@ -74,7 +78,7 @@ pub struct UploadSubmissionRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct UploadMapfixRequest{
|
pub struct UploadMapfixRequest{
|
||||||
pub MapfixID:i64,
|
pub MapfixID:MapfixID,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub TargetAssetID:u64,
|
pub TargetAssetID:u64,
|
||||||
|
|||||||
@@ -28,14 +28,6 @@ pub fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
|||||||
rbx_dom_weak::ustr(s)
|
rbx_dom_weak::ustr(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn class_is_a(class:&str,superclass:&str)->bool{
|
|
||||||
let db=rbx_reflection_database::get();
|
|
||||||
let (Some(class),Some(superclass))=(db.classes.get(class),db.classes.get(superclass))else{
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
db.has_superclass(class,superclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_first_child_name_and_class<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,name:&str,class:&str)->Option<&'a rbx_dom_weak::Instance>{
|
fn find_first_child_name_and_class<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,name:&str,class:&str)->Option<&'a rbx_dom_weak::Instance>{
|
||||||
instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|inst.name==name&&inst.class==class)
|
instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|inst.name==name&&inst.class==class)
|
||||||
}
|
}
|
||||||
@@ -45,6 +37,15 @@ pub enum GameID{
|
|||||||
Surf=2,
|
Surf=2,
|
||||||
FlyTrials=5,
|
FlyTrials=5,
|
||||||
}
|
}
|
||||||
|
impl From<GameID> for submissions_api::types::GameID{
|
||||||
|
fn from(value:GameID)->Self{
|
||||||
|
match value{
|
||||||
|
GameID::Bhop=>submissions_api::types::GameID::Bhop,
|
||||||
|
GameID::Surf=>submissions_api::types::GameID::Surf,
|
||||||
|
GameID::FlyTrials=>submissions_api::types::GameID::FlyTrials,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParseGameIDError;
|
pub struct ParseGameIDError;
|
||||||
impl std::str::FromStr for GameID{
|
impl std::str::FromStr for GameID{
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
pub enum ResourceID{
|
|
||||||
Mapfix(i64),
|
|
||||||
Submission(i64),
|
|
||||||
}
|
|
||||||
@@ -22,17 +22,23 @@ impl crate::message_handler::MessageHandler{
|
|||||||
Ok(())=>{
|
Ok(())=>{
|
||||||
// update the mapfix model status to validated
|
// update the mapfix model status to validated
|
||||||
self.api.action_mapfix_validated(
|
self.api.action_mapfix_validated(
|
||||||
submissions_api::types::MapfixID(mapfix_id)
|
mapfix_id
|
||||||
).await.map_err(Error::ApiActionMapfixValidate)?;
|
).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||||
},
|
},
|
||||||
Err(e)=>{
|
Err(e)=>{
|
||||||
// log error
|
// log error
|
||||||
println!("[validate_mapfix] Error: {e}");
|
println!("[validate_mapfix] Error: {e}");
|
||||||
|
|
||||||
|
self.api.create_mapfix_audit_error(
|
||||||
|
submissions_api::types::CreateMapfixAuditErrorRequest{
|
||||||
|
MapfixID:mapfix_id,
|
||||||
|
ErrorMessage:e.to_string(),
|
||||||
|
}
|
||||||
|
).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||||
|
|
||||||
// update the mapfix model status to accepted
|
// update the mapfix model status to accepted
|
||||||
self.api.action_mapfix_accepted(submissions_api::types::ActionMapfixAcceptedRequest{
|
self.api.action_mapfix_accepted(submissions_api::types::ActionMapfixAcceptedRequest{
|
||||||
MapfixID:mapfix_id,
|
MapfixID:mapfix_id,
|
||||||
ErrorMessage:e.to_string(),
|
|
||||||
}).await.map_err(Error::ApiActionMapfixValidate)?;
|
}).await.map_err(Error::ApiActionMapfixValidate)?;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,17 +22,23 @@ impl crate::message_handler::MessageHandler{
|
|||||||
Ok(())=>{
|
Ok(())=>{
|
||||||
// update the submission model status to validated
|
// update the submission model status to validated
|
||||||
self.api.action_submission_validated(
|
self.api.action_submission_validated(
|
||||||
submissions_api::types::SubmissionID(submission_id)
|
submission_id
|
||||||
).await.map_err(Error::ApiActionSubmissionValidate)?;
|
).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||||
},
|
},
|
||||||
Err(e)=>{
|
Err(e)=>{
|
||||||
// log error
|
// log error
|
||||||
println!("[validate_submission] Error: {e}");
|
println!("[validate_submission] Error: {e}");
|
||||||
|
|
||||||
|
self.api.create_submission_audit_error(
|
||||||
|
submissions_api::types::CreateSubmissionAuditErrorRequest{
|
||||||
|
SubmissionID:submission_id,
|
||||||
|
ErrorMessage:e.to_string(),
|
||||||
|
}
|
||||||
|
).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||||
|
|
||||||
// update the submission model status to accepted
|
// update the submission model status to accepted
|
||||||
self.api.action_submission_accepted(submissions_api::types::ActionSubmissionAcceptedRequest{
|
self.api.action_submission_accepted(submissions_api::types::ActionSubmissionAcceptedRequest{
|
||||||
SubmissionID:submission_id,
|
SubmissionID:submission_id,
|
||||||
ErrorMessage:e.to_string(),
|
|
||||||
}).await.map_err(Error::ApiActionSubmissionValidate)?;
|
}).await.map_err(Error::ApiActionSubmissionValidate)?;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use submissions_api::types::ResourceType;
|
use submissions_api::types::Resource;
|
||||||
|
|
||||||
use crate::download::download_asset_version;
|
use crate::download::download_asset_version;
|
||||||
use crate::rbx_util::{read_dom,static_ustr,ReadDomError};
|
use crate::rbx_util::{read_dom,static_ustr,ReadDomError};
|
||||||
use crate::types::ResourceID;
|
|
||||||
|
|
||||||
const SCRIPT_CONCURRENCY:usize=16;
|
const SCRIPT_CONCURRENCY:usize=16;
|
||||||
|
|
||||||
@@ -34,16 +33,22 @@ fn hash_source(source:&str)->String{
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
|
ModelInfoDownload(rbx_asset::cloud::GetError),
|
||||||
|
CreatorTypeMustBeUser,
|
||||||
|
RevisionMismatch{
|
||||||
|
current:u64,
|
||||||
|
submitted:u64,
|
||||||
|
},
|
||||||
ScriptFlaggedIllegalKeyword(String),
|
ScriptFlaggedIllegalKeyword(String),
|
||||||
ScriptBlocked(Option<submissions_api::types::ScriptID>),
|
ScriptBlocked(Option<submissions_api::types::ScriptID>),
|
||||||
ScriptNotYetReviewed(Option<submissions_api::types::ScriptID>),
|
ScriptNotYetReviewed(Option<submissions_api::types::ScriptID>),
|
||||||
Download(crate::download::Error),
|
Download(crate::download::Error),
|
||||||
ModelFileDecode(ReadDomError),
|
ModelFileDecode(ReadDomError),
|
||||||
ApiGetScriptPolicyFromHash(submissions_api::types::SingleItemError),
|
ApiGetScriptPolicyFromHash(submissions_api::types::ScriptPolicySingleItemError),
|
||||||
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),
|
ApiGetScriptFromHash(submissions_api::types::ScriptSingleItemError),
|
||||||
ApiUpdateMapfixModel(submissions_api::Error),
|
ApiUpdateMapfixModel(submissions_api::Error),
|
||||||
ApiUpdateSubmissionModel(submissions_api::Error),
|
ApiUpdateSubmissionModel(submissions_api::Error),
|
||||||
ModelFileRootMustHaveOneChild,
|
ModelFileRootMustHaveOneChild,
|
||||||
@@ -64,7 +69,7 @@ pub struct ValidateRequest{
|
|||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
pub ValidatedModelID:Option<u64>,
|
pub ValidatedModelID:Option<u64>,
|
||||||
pub ResourceID:ResourceID,
|
pub Resource:Resource,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
|
impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
|
||||||
@@ -73,7 +78,7 @@ impl From<crate::nats_types::ValidateMapfixRequest> for ValidateRequest{
|
|||||||
ModelID:value.ModelID,
|
ModelID:value.ModelID,
|
||||||
ModelVersion:value.ModelVersion,
|
ModelVersion:value.ModelVersion,
|
||||||
ValidatedModelID:value.ValidatedModelID,
|
ValidatedModelID:value.ValidatedModelID,
|
||||||
ResourceID:ResourceID::Mapfix(value.MapfixID),
|
Resource:Resource::Mapfix(value.MapfixID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,13 +88,31 @@ impl From<crate::nats_types::ValidateSubmissionRequest> for ValidateRequest{
|
|||||||
ModelID:value.ModelID,
|
ModelID:value.ModelID,
|
||||||
ModelVersion:value.ModelVersion,
|
ModelVersion:value.ModelVersion,
|
||||||
ValidatedModelID:value.ValidatedModelID,
|
ValidatedModelID:value.ValidatedModelID,
|
||||||
ResourceID:ResourceID::Submission(value.SubmissionID),
|
Resource:Resource::Submission(value.SubmissionID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::message_handler::MessageHandler{
|
impl crate::message_handler::MessageHandler{
|
||||||
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),Error>{
|
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),Error>{
|
||||||
|
// discover asset creator and latest version
|
||||||
|
let info=self.cloud_context.get_asset_info(
|
||||||
|
rbx_asset::cloud::GetAssetLatestRequest{asset_id:validate_info.ModelID}
|
||||||
|
).await.map_err(Error::ModelInfoDownload)?;
|
||||||
|
|
||||||
|
// reject models created by a group
|
||||||
|
let rbx_asset::cloud::Creator::userId(_user_id)=info.creationContext.creator else{
|
||||||
|
return Err(Error::CreatorTypeMustBeUser);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Has the map been updated since it was submitted?
|
||||||
|
if info.revisionId!=validate_info.ModelVersion{
|
||||||
|
return Err(Error::RevisionMismatch{
|
||||||
|
current:info.revisionId,
|
||||||
|
submitted:validate_info.ModelVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// download the map model
|
// download the map model
|
||||||
let maybe_gzip=download_asset_version(&self.cloud_context,rbx_asset::cloud::GetAssetVersionRequest{
|
let maybe_gzip=download_asset_version(&self.cloud_context,rbx_asset::cloud::GetAssetVersionRequest{
|
||||||
asset_id:validate_info.ModelID,
|
asset_id:validate_info.ModelID,
|
||||||
@@ -153,10 +176,7 @@ impl crate::message_handler::MessageHandler{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}else{
|
}else{
|
||||||
let (resource_type,resource_id)=match validate_info.ResourceID{
|
let (resource_type,resource_id)=validate_info.Resource.split();
|
||||||
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{
|
||||||
@@ -257,8 +277,8 @@ impl crate::message_handler::MessageHandler{
|
|||||||
(validate_info.ModelID,validate_info.ModelVersion)
|
(validate_info.ModelID,validate_info.ModelVersion)
|
||||||
};
|
};
|
||||||
|
|
||||||
match validate_info.ResourceID{
|
match validate_info.Resource{
|
||||||
ResourceID::Mapfix(mapfix_id)=>{
|
Resource::Mapfix(mapfix_id)=>{
|
||||||
// update the mapfix to use the validated model
|
// update the mapfix to use the validated model
|
||||||
self.api.update_mapfix_validated_model(submissions_api::types::UpdateMapfixModelRequest{
|
self.api.update_mapfix_validated_model(submissions_api::types::UpdateMapfixModelRequest{
|
||||||
MapfixID:mapfix_id,
|
MapfixID:mapfix_id,
|
||||||
@@ -266,7 +286,7 @@ impl crate::message_handler::MessageHandler{
|
|||||||
ModelVersion:validated_model_version,
|
ModelVersion:validated_model_version,
|
||||||
}).await.map_err(Error::ApiUpdateMapfixModel)?;
|
}).await.map_err(Error::ApiUpdateMapfixModel)?;
|
||||||
},
|
},
|
||||||
ResourceID::Submission(submission_id)=>{
|
Resource::Submission(submission_id)=>{
|
||||||
// update the submission to use the validated model
|
// update the submission to use the validated model
|
||||||
self.api.update_submission_validated_model(submissions_api::types::UpdateSubmissionModelRequest{
|
self.api.update_submission_validated_model(submissions_api::types::UpdateSubmissionModelRequest{
|
||||||
SubmissionID:submission_id,
|
SubmissionID:submission_id,
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ const nextConfig: NextConfig = {
|
|||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
protocol: "https",
|
protocol: "https",
|
||||||
hostname: "tr.rbxcdn.com",
|
hostname: "**.rbxcdn.com",
|
||||||
pathname: "/**",
|
|
||||||
port: "",
|
|
||||||
search: "",
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,20 +11,23 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@mui/icons-material": "^6.1.10",
|
"@mui/icons-material": "^6.1.10",
|
||||||
"@mui/material": "^6.1.10",
|
"@mui/material": "^6.1.10",
|
||||||
|
"date-fns": "^4.1.0",
|
||||||
"next": "^15.1.0",
|
"next": "^15.1.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"sass": "^1.82.0"
|
"sass": "^1.82.0",
|
||||||
|
"swr": "^2.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.7.2",
|
"@eslint/eslintrc": "^3.2.0",
|
||||||
"@types/node": "^20.17.9",
|
"@types/node": "^20.17.9",
|
||||||
"@types/react": "^19.0.1",
|
"@types/react": "^19.0.1",
|
||||||
"@types/react-dom": "^19.0.2",
|
"@types/react-dom": "^19.0.2",
|
||||||
"eslint": "^9.16.0",
|
"eslint": "^9.16.0",
|
||||||
"eslint-config-next": "15.1.0",
|
"eslint-config-next": "15.1.0",
|
||||||
"@eslint/eslintrc": "^3.2.0"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
web/src/app/_components/AppProviders.tsx
Normal file
15
web/src/app/_components/AppProviders.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ThemeProvider } from "@mui/material";
|
||||||
|
import { SessionProvider } from "@/app/_components/SessionContext";
|
||||||
|
import { theme } from "@/app/lib/theme";
|
||||||
|
|
||||||
|
export default function AppProviders({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<SessionProvider>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</SessionProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
43
web/src/app/_components/ErrorDisplay.tsx
Normal file
43
web/src/app/_components/ErrorDisplay.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { Button, Container, Paper, Typography } from "@mui/material";
|
||||||
|
import Webpage from "@/app/_components/webpage";
|
||||||
|
|
||||||
|
interface ErrorDisplayProps {
|
||||||
|
title: string;
|
||||||
|
message: string;
|
||||||
|
buttonText?: string;
|
||||||
|
onButtonClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ErrorDisplay({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
buttonText,
|
||||||
|
onButtonClick
|
||||||
|
}: ErrorDisplayProps) {
|
||||||
|
return (
|
||||||
|
<Webpage>
|
||||||
|
<Container maxWidth="lg" sx={{ py: 6 }}>
|
||||||
|
<Paper
|
||||||
|
elevation={3}
|
||||||
|
sx={{
|
||||||
|
p: 4,
|
||||||
|
textAlign: 'center',
|
||||||
|
borderRadius: 2
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h5" gutterBottom>{title}</Typography>
|
||||||
|
<Typography variant="body1">{message}</Typography>
|
||||||
|
{buttonText && onButtonClick && (
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={onButtonClick}
|
||||||
|
sx={{ mt: 3 }}
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
</Webpage>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
web/src/app/_components/SessionContext.tsx
Normal file
48
web/src/app/_components/SessionContext.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { createContext, useContext, ReactNode } from "react";
|
||||||
|
import useSWR from "swr";
|
||||||
|
import { RolesConstants } from "@/app/ts/Roles";
|
||||||
|
|
||||||
|
interface UserInfo {
|
||||||
|
UserID: number;
|
||||||
|
Username: string;
|
||||||
|
AvatarURL: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SessionContextType {
|
||||||
|
roles: number;
|
||||||
|
user: UserInfo | null;
|
||||||
|
loading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SessionContext = createContext<SessionContextType>({ roles: RolesConstants.Empty, user: null, loading: true });
|
||||||
|
|
||||||
|
const fetcher = async (url: string) => {
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) return null;
|
||||||
|
try {
|
||||||
|
const data = await res.json();
|
||||||
|
if (data && typeof data === 'object' && (data.code || data.error)) return null;
|
||||||
|
return data;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SessionProvider = ({ children }: { children: ReactNode }) => {
|
||||||
|
const { data: rolesData, isLoading: rolesLoading } = useSWR("/api/session/roles", fetcher, { refreshInterval: 60000 });
|
||||||
|
const { data: userData, isLoading: userLoading } = useSWR("/api/session/user", fetcher, { refreshInterval: 60000 });
|
||||||
|
|
||||||
|
const loading = rolesLoading || userLoading;
|
||||||
|
const roles = rolesData?.Roles ?? RolesConstants.Empty;
|
||||||
|
const user = userData ?? null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SessionContext.Provider value={{ roles, user, loading }}>
|
||||||
|
{children}
|
||||||
|
</SessionContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSession = () => useContext(SessionContext);
|
||||||
151
web/src/app/_components/carousel.tsx
Normal file
151
web/src/app/_components/carousel.tsx
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import {Box, IconButton, Typography} from "@mui/material";
|
||||||
|
import {useEffect, useRef, useState} from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
|
||||||
|
import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos";
|
||||||
|
import {SubmissionInfo} from "@/app/ts/Submission";
|
||||||
|
import {MapfixInfo} from "@/app/ts/Mapfix";
|
||||||
|
|
||||||
|
// Type for the items in the carousel
|
||||||
|
type CarouselItem = SubmissionInfo | MapfixInfo;
|
||||||
|
|
||||||
|
// Props for the Carousel component
|
||||||
|
interface CarouselProps<T extends CarouselItem> {
|
||||||
|
title: string;
|
||||||
|
items: T[] | undefined;
|
||||||
|
renderItem: (item: T) => React.ReactNode;
|
||||||
|
viewAllLink: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Carousel<T extends CarouselItem>({ title, items, renderItem, viewAllLink }: CarouselProps<T>) {
|
||||||
|
const carouselRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const [scrollPosition, setScrollPosition] = useState<number>(0);
|
||||||
|
const [maxScroll, setMaxScroll] = useState<number>(0);
|
||||||
|
|
||||||
|
const SCROLL_AMOUNT = 300;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (carouselRef.current) {
|
||||||
|
const scrollWidth = carouselRef.current.scrollWidth;
|
||||||
|
const clientWidth = carouselRef.current.clientWidth;
|
||||||
|
setMaxScroll(scrollWidth - clientWidth);
|
||||||
|
}
|
||||||
|
}, [items]);
|
||||||
|
|
||||||
|
const scroll = (direction: 'left' | 'right'): void => {
|
||||||
|
if (carouselRef.current) {
|
||||||
|
const scrollAmount = direction === 'left' ? -SCROLL_AMOUNT : SCROLL_AMOUNT;
|
||||||
|
|
||||||
|
carouselRef.current.scrollBy({
|
||||||
|
left: scrollAmount,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (carouselRef.current) {
|
||||||
|
setScrollPosition(carouselRef.current.scrollLeft);
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
if (carouselRef.current) {
|
||||||
|
setScrollPosition(carouselRef.current.scrollLeft);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ref = carouselRef.current;
|
||||||
|
if (ref) {
|
||||||
|
ref.addEventListener('scroll', handleScroll);
|
||||||
|
return () => ref.removeEventListener('scroll', handleScroll);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box mb={6}>
|
||||||
|
<Box display="flex" justifyContent="space-between" alignItems="center" mb={2}>
|
||||||
|
<Typography variant="h4" component="h2" fontWeight="bold">
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
<Link href={viewAllLink} style={{textDecoration: 'none'}}>
|
||||||
|
<Typography component="span" color="primary">
|
||||||
|
View All →
|
||||||
|
</Typography>
|
||||||
|
</Link>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box position="relative">
|
||||||
|
<IconButton
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: -20,
|
||||||
|
top: '50%',
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
zIndex: 2,
|
||||||
|
backgroundColor: 'background.paper',
|
||||||
|
boxShadow: 2,
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'action.hover',
|
||||||
|
},
|
||||||
|
visibility: scrollPosition <= 5 ? 'hidden' : 'visible',
|
||||||
|
}}
|
||||||
|
onClick={() => scroll('left')}
|
||||||
|
>
|
||||||
|
<ArrowBackIosNewIcon />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
ref={carouselRef}
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
overflowX: 'auto',
|
||||||
|
scrollbarWidth: 'none',
|
||||||
|
msOverflowStyle: 'none',
|
||||||
|
'&::-webkit-scrollbar': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
gap: '16px', // Fixed 16px gap - using string with px unit to ensure it's absolute
|
||||||
|
padding: '8px 4px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{items?.map((item, index) => (
|
||||||
|
<Box
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
flex: '0 0 auto',
|
||||||
|
width: {
|
||||||
|
xs: '260px', // Fixed width at different breakpoints
|
||||||
|
sm: '280px',
|
||||||
|
md: '300px'
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{renderItem(item)}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
right: -20,
|
||||||
|
top: '50%',
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
zIndex: 2,
|
||||||
|
backgroundColor: 'background.paper',
|
||||||
|
boxShadow: 2,
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'action.hover',
|
||||||
|
},
|
||||||
|
visibility: scrollPosition >= maxScroll - 5 ? 'hidden' : 'visible',
|
||||||
|
}}
|
||||||
|
onClick={() => scroll('right')}
|
||||||
|
>
|
||||||
|
<ArrowForwardIosIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
54
web/src/app/_components/comments/AuditEventItem.tsx
Normal file
54
web/src/app/_components/comments/AuditEventItem.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Avatar,
|
||||||
|
Typography,
|
||||||
|
Tooltip
|
||||||
|
} from "@mui/material";
|
||||||
|
import PersonIcon from '@mui/icons-material/Person';
|
||||||
|
import { formatDistanceToNow, format } from "date-fns";
|
||||||
|
import { AuditEvent, decodeAuditEvent as auditEventMessage } from "@/app/ts/AuditEvent";
|
||||||
|
|
||||||
|
interface AuditEventItemProps {
|
||||||
|
event: AuditEvent;
|
||||||
|
validatorUser: number;
|
||||||
|
userAvatarUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AuditEventItem({ event, validatorUser, userAvatarUrl }: AuditEventItemProps) {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||||
|
<Avatar
|
||||||
|
src={event.User === validatorUser ? undefined : userAvatarUrl}
|
||||||
|
sx={{ border: '1px solid rgba(255, 255, 255, 0.1)', bgcolor: 'grey.900' }}
|
||||||
|
>
|
||||||
|
<PersonIcon />
|
||||||
|
</Avatar>
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
|
<Typography variant="subtitle2">
|
||||||
|
{event.User === validatorUser ? "Validator" : event.Username || "Unknown"}
|
||||||
|
</Typography>
|
||||||
|
<DateDisplay date={event.Date} />
|
||||||
|
</Box>
|
||||||
|
<Typography variant="body2">{auditEventMessage(event)}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DateDisplayProps {
|
||||||
|
date: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DateDisplay({ date }: DateDisplayProps) {
|
||||||
|
return (
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
<Tooltip title={format(new Date(date * 1000), 'PPpp')}>
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
{formatDistanceToNow(new Date(date * 1000), { addSuffix: true })}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
42
web/src/app/_components/comments/AuditEventsTabPanel.tsx
Normal file
42
web/src/app/_components/comments/AuditEventsTabPanel.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Stack,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { AuditEvent, AuditEventType } from "@/app/ts/AuditEvent";
|
||||||
|
import AuditEventItem from './AuditEventItem';
|
||||||
|
|
||||||
|
interface AuditEventsTabPanelProps {
|
||||||
|
activeTab: number;
|
||||||
|
auditEvents: AuditEvent[];
|
||||||
|
validatorUser: number;
|
||||||
|
auditEventUserAvatarUrls?: Record<number, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AuditEventsTabPanel({
|
||||||
|
activeTab,
|
||||||
|
auditEvents,
|
||||||
|
validatorUser,
|
||||||
|
auditEventUserAvatarUrls
|
||||||
|
}: AuditEventsTabPanelProps) {
|
||||||
|
const filteredEvents = auditEvents.filter(
|
||||||
|
event => event.EventType !== AuditEventType.Comment
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box role="tabpanel" hidden={activeTab !== 1}>
|
||||||
|
{activeTab === 1 && (
|
||||||
|
<Stack spacing={2}>
|
||||||
|
{filteredEvents.map((event, index) => (
|
||||||
|
<AuditEventItem
|
||||||
|
key={index}
|
||||||
|
event={event}
|
||||||
|
validatorUser={validatorUser}
|
||||||
|
userAvatarUrl={auditEventUserAvatarUrls?.[event.User]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
54
web/src/app/_components/comments/CommentItem.tsx
Normal file
54
web/src/app/_components/comments/CommentItem.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Avatar,
|
||||||
|
Typography,
|
||||||
|
Tooltip
|
||||||
|
} from "@mui/material";
|
||||||
|
import PersonIcon from '@mui/icons-material/Person';
|
||||||
|
import { formatDistanceToNow, format } from "date-fns";
|
||||||
|
import { AuditEvent, decodeAuditEvent } from "@/app/ts/AuditEvent";
|
||||||
|
|
||||||
|
interface CommentItemProps {
|
||||||
|
event: AuditEvent;
|
||||||
|
validatorUser: number;
|
||||||
|
userAvatarUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CommentItem({ event, validatorUser, userAvatarUrl }: CommentItemProps) {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||||
|
<Avatar
|
||||||
|
src={event.User === validatorUser ? undefined : userAvatarUrl}
|
||||||
|
sx={{ border: '1px solid rgba(255, 255, 255, 0.1)', bgcolor: 'grey.900' }}
|
||||||
|
>
|
||||||
|
<PersonIcon />
|
||||||
|
</Avatar>
|
||||||
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
|
<Typography variant="subtitle2">
|
||||||
|
{event.User === validatorUser ? "Validator" : event.Username || "Unknown"}
|
||||||
|
</Typography>
|
||||||
|
<DateDisplay date={event.Date} />
|
||||||
|
</Box>
|
||||||
|
<Typography variant="body2">{decodeAuditEvent(event)}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DateDisplayProps {
|
||||||
|
date: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DateDisplay({ date }: DateDisplayProps) {
|
||||||
|
return (
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
<Tooltip title={format(new Date(date * 1000), 'PPpp')}>
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
{formatDistanceToNow(new Date(date * 1000), { addSuffix: true })}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
70
web/src/app/_components/comments/CommentsAndAuditSection.tsx
Normal file
70
web/src/app/_components/comments/CommentsAndAuditSection.tsx
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import React, {useState} from 'react';
|
||||||
|
import {
|
||||||
|
Paper,
|
||||||
|
Box,
|
||||||
|
Tabs,
|
||||||
|
Tab,
|
||||||
|
} from "@mui/material";
|
||||||
|
import CommentsTabPanel from './CommentsTabPanel';
|
||||||
|
import AuditEventsTabPanel from './AuditEventsTabPanel';
|
||||||
|
import { AuditEvent } from "@/app/ts/AuditEvent";
|
||||||
|
|
||||||
|
interface CommentsAndAuditSectionProps {
|
||||||
|
auditEvents: AuditEvent[];
|
||||||
|
newComment: string;
|
||||||
|
setNewComment: (comment: string) => void;
|
||||||
|
handleCommentSubmit: () => void;
|
||||||
|
validatorUser: number;
|
||||||
|
userId: number | null;
|
||||||
|
commentUserAvatarUrls: Record<number, string>;
|
||||||
|
auditEventUserAvatarUrls?: Record<number, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CommentsAndAuditSection({
|
||||||
|
auditEvents,
|
||||||
|
newComment,
|
||||||
|
setNewComment,
|
||||||
|
handleCommentSubmit,
|
||||||
|
validatorUser,
|
||||||
|
userId,
|
||||||
|
commentUserAvatarUrls,
|
||||||
|
auditEventUserAvatarUrls
|
||||||
|
}: CommentsAndAuditSectionProps) {
|
||||||
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
|
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
||||||
|
setActiveTab(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper sx={{ p: 3, mt: 3 }}>
|
||||||
|
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>
|
||||||
|
<Tabs
|
||||||
|
value={activeTab}
|
||||||
|
onChange={handleTabChange}
|
||||||
|
aria-label="comments and audit tabs"
|
||||||
|
>
|
||||||
|
<Tab label="Comments" />
|
||||||
|
<Tab label="Audit Events" />
|
||||||
|
</Tabs>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<CommentsTabPanel
|
||||||
|
activeTab={activeTab}
|
||||||
|
auditEvents={auditEvents}
|
||||||
|
validatorUser={validatorUser}
|
||||||
|
newComment={newComment}
|
||||||
|
setNewComment={setNewComment}
|
||||||
|
handleCommentSubmit={handleCommentSubmit}
|
||||||
|
userId={userId}
|
||||||
|
commentUserAvatarUrls={commentUserAvatarUrls}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AuditEventsTabPanel
|
||||||
|
activeTab={activeTab}
|
||||||
|
auditEvents={auditEvents}
|
||||||
|
validatorUser={validatorUser}
|
||||||
|
auditEventUserAvatarUrls={auditEventUserAvatarUrls}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
108
web/src/app/_components/comments/CommentsTabPanel.tsx
Normal file
108
web/src/app/_components/comments/CommentsTabPanel.tsx
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Stack,
|
||||||
|
Avatar,
|
||||||
|
TextField,
|
||||||
|
IconButton
|
||||||
|
} from "@mui/material";
|
||||||
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
|
import { AuditEvent, AuditEventType } from "@/app/ts/AuditEvent";
|
||||||
|
import CommentItem from './CommentItem';
|
||||||
|
|
||||||
|
interface CommentsTabPanelProps {
|
||||||
|
activeTab: number;
|
||||||
|
auditEvents: AuditEvent[];
|
||||||
|
validatorUser: number;
|
||||||
|
newComment: string;
|
||||||
|
setNewComment: (comment: string) => void;
|
||||||
|
handleCommentSubmit: () => void;
|
||||||
|
userId: number | null;
|
||||||
|
userAvatarUrl?: string;
|
||||||
|
commentUserAvatarUrls?: Record<number, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CommentsTabPanel({
|
||||||
|
activeTab,
|
||||||
|
auditEvents,
|
||||||
|
validatorUser,
|
||||||
|
newComment,
|
||||||
|
setNewComment,
|
||||||
|
handleCommentSubmit,
|
||||||
|
userId,
|
||||||
|
userAvatarUrl,
|
||||||
|
commentUserAvatarUrls
|
||||||
|
}: CommentsTabPanelProps) {
|
||||||
|
const commentEvents = auditEvents.filter(
|
||||||
|
event => event.EventType === AuditEventType.Comment
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box role="tabpanel" hidden={activeTab !== 0}>
|
||||||
|
{activeTab === 0 && (
|
||||||
|
<>
|
||||||
|
<Stack spacing={2} sx={{ mb: 3 }}>
|
||||||
|
{commentEvents.length > 0 ? (
|
||||||
|
commentEvents.map((event, index) => (
|
||||||
|
<CommentItem
|
||||||
|
key={index}
|
||||||
|
event={event}
|
||||||
|
validatorUser={validatorUser}
|
||||||
|
userAvatarUrl={commentUserAvatarUrls?.[event.User]}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Box sx={{ textAlign: 'center', py: 2, color: 'text.secondary' }}>
|
||||||
|
No Comments
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{userId !== null && (
|
||||||
|
<CommentInput
|
||||||
|
newComment={newComment}
|
||||||
|
setNewComment={setNewComment}
|
||||||
|
handleCommentSubmit={handleCommentSubmit}
|
||||||
|
userId={userId}
|
||||||
|
userAvatarUrl={userAvatarUrl}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CommentInputProps {
|
||||||
|
newComment: string;
|
||||||
|
setNewComment: (comment: string) => void;
|
||||||
|
handleCommentSubmit: () => void;
|
||||||
|
userId: number | null;
|
||||||
|
userAvatarUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CommentInput({ newComment, setNewComment, handleCommentSubmit, userAvatarUrl }: CommentInputProps) {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', gap: 2, alignItems: 'flex-start' }}>
|
||||||
|
<Avatar
|
||||||
|
src={userAvatarUrl}
|
||||||
|
sx={{ border: '1px solid rgba(255, 255, 255, 0.1)', bgcolor: 'grey.900' }}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
multiline
|
||||||
|
rows={2}
|
||||||
|
placeholder="Add a comment..."
|
||||||
|
value={newComment}
|
||||||
|
onChange={(e) => setNewComment(e.target.value)}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
color="primary"
|
||||||
|
onClick={handleCommentSubmit}
|
||||||
|
disabled={!newComment.trim()}
|
||||||
|
>
|
||||||
|
<SendIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,63 +2,277 @@
|
|||||||
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useSession } from "@/app/_components/SessionContext";
|
||||||
|
|
||||||
import "./styles/header.scss"
|
import AppBar from "@mui/material/AppBar";
|
||||||
import { UserInfo } from "@/app/ts/User";
|
import Toolbar from "@mui/material/Toolbar";
|
||||||
import { useState, useEffect } from "react";
|
import Button from "@mui/material/Button";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import Menu from "@mui/material/Menu";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import IconButton from "@mui/material/IconButton";
|
||||||
|
import MenuIcon from "@mui/icons-material/Menu";
|
||||||
|
import Drawer from "@mui/material/Drawer";
|
||||||
|
import List from "@mui/material/List";
|
||||||
|
import ListItem from "@mui/material/ListItem";
|
||||||
|
import ListItemButton from "@mui/material/ListItemButton";
|
||||||
|
import ListItemText from "@mui/material/ListItemText";
|
||||||
|
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||||
|
import { useTheme } from "@mui/material/styles";
|
||||||
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||||
|
import { RolesConstants, hasRole } from "@/app/ts/Roles";
|
||||||
|
|
||||||
interface HeaderButton {
|
interface HeaderButton {
|
||||||
name: string,
|
name: string;
|
||||||
href: string
|
href: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const navItems: HeaderButton[] = [
|
||||||
|
{ name: "Home", href: "/" },
|
||||||
|
{ name: "Submissions", href: "/submissions" },
|
||||||
|
{ name: "Mapfixes", href: "/mapfixes" },
|
||||||
|
{ name: "Maps", href: "/maps" },
|
||||||
|
];
|
||||||
|
|
||||||
function HeaderButton(header: HeaderButton) {
|
function HeaderButton(header: HeaderButton) {
|
||||||
return (
|
return (
|
||||||
<Link href={header.href}>
|
<Button color="inherit" component={Link} href={header.href}>
|
||||||
<button>{header.name}</button>
|
{header.name}
|
||||||
</Link>
|
</Button>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const handleLoginClick = () => {
|
const theme = useTheme();
|
||||||
window.location.href = "/auth/oauth2/login?redirect=" + window.location.href;
|
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
};
|
const [mobileOpen, setMobileOpen] = useState(false);
|
||||||
|
|
||||||
const [valid, setValid] = useState<boolean>(false)
|
const { user, roles } = useSession();
|
||||||
const [user, setUser] = useState<UserInfo | null>(null)
|
const valid = !!user;
|
||||||
|
|
||||||
useEffect(() => {
|
const handleLoginClick = () => {
|
||||||
async function getLoginInfo() {
|
window.location.href =
|
||||||
const [validateData, userData] = await Promise.all([
|
"/auth/oauth2/login?redirect=" + window.location.href;
|
||||||
fetch("/api/session/validate").then(validateResponse => validateResponse.json()),
|
};
|
||||||
fetch("/api/session/user").then(userResponse => userResponse.json())
|
|
||||||
]);
|
|
||||||
setValid(validateData)
|
|
||||||
setUser(userData)
|
|
||||||
}
|
|
||||||
getLoginInfo()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||||
<header className="header-bar">
|
const [quickLinksAnchor, setQuickLinksAnchor] = useState<null | HTMLElement>(null);
|
||||||
<nav className="left">
|
|
||||||
<HeaderButton name="Submissions" href="/submissions"/>
|
const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
<HeaderButton name="Mapfixes" href="/mapfixes"/>
|
setAnchorEl(event.currentTarget);
|
||||||
<HeaderButton name="Maps" href="/maps"/>
|
};
|
||||||
</nav>
|
|
||||||
<nav className="right">
|
const handleMenuClose = () => {
|
||||||
<HeaderButton name="Submit" href="/submit"/>
|
setAnchorEl(null);
|
||||||
{valid && user ? (
|
};
|
||||||
<div className="author">
|
|
||||||
<Link href="/auth">
|
const handleDrawerToggle = () => {
|
||||||
<Image className="avatar" width={28} height={28} priority={true} src={user.AvatarURL} alt={user.Username}/>
|
setMobileOpen(!mobileOpen);
|
||||||
<button>{user.Username}</button>
|
};
|
||||||
</Link>
|
|
||||||
</div>
|
const handleQuickLinksOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
) : (
|
setQuickLinksAnchor(event.currentTarget);
|
||||||
<button onClick={handleLoginClick}>Login</button>
|
};
|
||||||
)}
|
const handleQuickLinksClose = () => {
|
||||||
</nav>
|
setQuickLinksAnchor(null);
|
||||||
</header>
|
};
|
||||||
)
|
|
||||||
}
|
// Mobile navigation drawer content
|
||||||
|
const drawer = (
|
||||||
|
<Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}>
|
||||||
|
<List>
|
||||||
|
{navItems.map((item) => (
|
||||||
|
<ListItem key={item.name} disablePadding>
|
||||||
|
<ListItemButton component={Link} href={item.href} sx={{ textAlign: 'center' }}>
|
||||||
|
<ListItemText primary={item.name} />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
{valid && user && (
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton component={Link} href="/submit" sx={{ textAlign: 'center' }}>
|
||||||
|
<ListItemText primary="Submit Map" sx={{ color: 'success.main' }} />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
|
{!valid && (
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton onClick={handleLoginClick} sx={{ textAlign: 'center' }}>
|
||||||
|
<ListItemText primary="Login" />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
|
{valid && user && (
|
||||||
|
<ListItem disablePadding>
|
||||||
|
<ListItemButton component={Link} href="/auth" sx={{ textAlign: 'center' }}>
|
||||||
|
<ListItemText primary="Manage Account" />
|
||||||
|
</ListItemButton>
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
|
</List>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
const quickLinks = [
|
||||||
|
{ name: "Bhop", href: "https://www.roblox.com/games/5315046213" },
|
||||||
|
{ name: "Bhop Maptest", href: "https://www.roblox.com/games/517201717" },
|
||||||
|
{ name: "Surf", href: "https://www.roblox.com/games/5315066937" },
|
||||||
|
{ name: "Surf Maptest", href: "https://www.roblox.com/games/517206177" },
|
||||||
|
{ name: "Fly Trials", href: "https://www.roblox.com/games/12591611759" },
|
||||||
|
{ name: "Fly Trials Maptest", href: "https://www.roblox.com/games/12724901535" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const showScriptReview = hasRole(roles, RolesConstants.ScriptWrite);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppBar position="static">
|
||||||
|
<Toolbar>
|
||||||
|
{isMobile && (
|
||||||
|
<IconButton
|
||||||
|
color="inherit"
|
||||||
|
aria-label="open drawer"
|
||||||
|
edge="start"
|
||||||
|
onClick={handleDrawerToggle}
|
||||||
|
sx={{ mr: 2 }}
|
||||||
|
>
|
||||||
|
<MenuIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Desktop navigation */}
|
||||||
|
{!isMobile && (
|
||||||
|
<Box display="flex" flexGrow={1} gap={2} alignItems="center">
|
||||||
|
{navItems.map((item) => (
|
||||||
|
<HeaderButton key={item.name} name={item.name} href={item.href} />
|
||||||
|
))}
|
||||||
|
{showScriptReview && (
|
||||||
|
<HeaderButton name="Script Review" href="/script-review" />
|
||||||
|
)}
|
||||||
|
<Box sx={{ flexGrow: 1 }} /> {/* Push quick links to the right */}
|
||||||
|
{/* Quick Links Dropdown */}
|
||||||
|
<Box>
|
||||||
|
<Button
|
||||||
|
color="inherit"
|
||||||
|
endIcon={<ArrowDropDownIcon />}
|
||||||
|
onClick={handleQuickLinksOpen}
|
||||||
|
sx={{ textTransform: 'none', fontSize: '0.95rem', px: 1 }}
|
||||||
|
>
|
||||||
|
QUICK LINKS
|
||||||
|
</Button>
|
||||||
|
<Menu
|
||||||
|
anchorEl={quickLinksAnchor}
|
||||||
|
open={Boolean(quickLinksAnchor)}
|
||||||
|
onClose={handleQuickLinksClose}
|
||||||
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||||
|
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||||
|
>
|
||||||
|
{quickLinks.map(link => (
|
||||||
|
<MenuItem
|
||||||
|
key={link.name}
|
||||||
|
onClick={handleQuickLinksClose}
|
||||||
|
sx={{ minWidth: 180 }}
|
||||||
|
component="a"
|
||||||
|
href={link.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Menu>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Spacer for mobile view */}
|
||||||
|
{isMobile && <Box sx={{ flexGrow: 1 }} />}
|
||||||
|
|
||||||
|
{/* Right side of nav */}
|
||||||
|
<Box display="flex" gap={2}>
|
||||||
|
{!isMobile && valid && user && (
|
||||||
|
<Button variant="outlined" color="success" component={Link} href="/submit">
|
||||||
|
Submit Map
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{!isMobile && valid && user ? (
|
||||||
|
<Box display="flex" alignItems="center">
|
||||||
|
<Button
|
||||||
|
onClick={handleMenuOpen}
|
||||||
|
color="inherit"
|
||||||
|
size="small"
|
||||||
|
style={{ textTransform: "none" }}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
className="avatar"
|
||||||
|
width={28}
|
||||||
|
height={28}
|
||||||
|
priority={true}
|
||||||
|
src={user.AvatarURL}
|
||||||
|
alt={user.Username}
|
||||||
|
style={{ marginRight: 8 }}
|
||||||
|
/>
|
||||||
|
<Typography variant="body1">{user.Username}</Typography>
|
||||||
|
</Button>
|
||||||
|
<Menu
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={Boolean(anchorEl)}
|
||||||
|
onClose={handleMenuClose}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: "bottom",
|
||||||
|
horizontal: "left",
|
||||||
|
}}
|
||||||
|
transformOrigin={{
|
||||||
|
vertical: "top",
|
||||||
|
horizontal: "left",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem component={Link} href="/auth">
|
||||||
|
Manage
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</Box>
|
||||||
|
) : !isMobile && (
|
||||||
|
<Button color="inherit" onClick={handleLoginClick}>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* In mobile view, display just the avatar if logged in */}
|
||||||
|
{isMobile && valid && user && (
|
||||||
|
<IconButton
|
||||||
|
onClick={handleMenuOpen}
|
||||||
|
color="inherit"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
className="avatar"
|
||||||
|
width={28}
|
||||||
|
height={28}
|
||||||
|
priority={true}
|
||||||
|
src={user.AvatarURL}
|
||||||
|
alt={user.Username}
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
{/* Mobile drawer */}
|
||||||
|
<Drawer
|
||||||
|
variant="temporary"
|
||||||
|
open={mobileOpen}
|
||||||
|
onClose={handleDrawerToggle}
|
||||||
|
ModalProps={{
|
||||||
|
keepMounted: true, // Better open performance on mobile
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: 240 },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{drawer}
|
||||||
|
</Drawer>
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,71 +1,193 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Image from "next/image";
|
import {Avatar, Box, Card, CardActionArea, CardContent, CardMedia, CircularProgress, Divider, Grid, Typography} from "@mui/material";
|
||||||
import Link from "next/link";
|
import {Explore, Person2} from "@mui/icons-material";
|
||||||
import { Rating } from "@mui/material";
|
import {StatusChip} from "@/app/_components/statusChip";
|
||||||
|
|
||||||
interface SubmissionCardProps {
|
interface MapCardProps {
|
||||||
displayName: string;
|
displayName: string;
|
||||||
assetId: number;
|
assetId: number;
|
||||||
authorId: number;
|
submitterId: number;
|
||||||
|
submitterUsername: string;
|
||||||
author: string;
|
author: string;
|
||||||
rating: number;
|
rating: number;
|
||||||
id: number;
|
id: number;
|
||||||
|
statusID: number;
|
||||||
|
gameID: number;
|
||||||
|
created: number;
|
||||||
|
type: 'mapfix' | 'submission';
|
||||||
|
thumbnailUrl?: string;
|
||||||
|
authorAvatarUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SubmissionCard(props: SubmissionCardProps) {
|
const CARD_WIDTH = 270;
|
||||||
return (
|
|
||||||
<Link href={`/submissions/${props.id}`}>
|
|
||||||
<div className="submissionCard">
|
|
||||||
<div className="content">
|
|
||||||
<div className="map-image">
|
|
||||||
{/* TODO: Grab image of model */}
|
|
||||||
<Image width={230} height={230} layout="fixed" priority={true} src={`/thumbnails/asset/${props.assetId}`} alt={props.displayName} />
|
|
||||||
</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={`/thumbnails/user/${props.authorId}`} alt={props.author}/>
|
|
||||||
<span>{props.author}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MapfixCard(props: SubmissionCardProps) {
|
export function MapCard(props: MapCardProps) {
|
||||||
return (
|
return (
|
||||||
<Link href={`/mapfixes/${props.id}`}>
|
<Grid item xs={12} sm={6} md={3} key={props.assetId}>
|
||||||
<div className="MapfixCard">
|
<Box sx={{
|
||||||
<div className="content">
|
width: CARD_WIDTH,
|
||||||
<div className="map-image">
|
mx: 'auto', // Center the card in its grid cell
|
||||||
{/* TODO: Grab image of model */}
|
}}>
|
||||||
<Image width={230} height={230} layout="fixed" priority={true} src={`/thumbnails/asset/${props.assetId}`} alt={props.displayName} />
|
<Card sx={{
|
||||||
</div>
|
width: CARD_WIDTH,
|
||||||
<div className="details">
|
height: 340, // Fixed height for all cards
|
||||||
<div className="header">
|
display: 'flex',
|
||||||
<span className="displayName">{props.displayName}</span>
|
flexDirection: 'column',
|
||||||
<div className="rating">
|
}}>
|
||||||
<Rating value={props.rating} readOnly size="small" />
|
<CardActionArea
|
||||||
</div>
|
sx={{
|
||||||
</div>
|
height: '100%',
|
||||||
<div className="footer">
|
display: 'flex',
|
||||||
<div className="author">
|
flexDirection: 'column',
|
||||||
<Image className="avatar" width={28} height={28} priority={true} src={`/thumbnails/user/${props.authorId}`} alt={props.author}/>
|
alignItems: 'stretch'
|
||||||
<span>{props.author}</span>
|
}}
|
||||||
</div>
|
href={`/${props.type === 'submission' ? 'submissions' : 'mapfixes'}/${props.id}`}>
|
||||||
</div>
|
<Box sx={{ position: 'relative' }}>
|
||||||
</div>
|
{props.thumbnailUrl ? (
|
||||||
</div>
|
<CardMedia
|
||||||
</div>
|
component="img"
|
||||||
</Link>
|
image={props.thumbnailUrl}
|
||||||
);
|
alt={props.displayName}
|
||||||
|
sx={{
|
||||||
|
height: 160, // Fixed height for all images
|
||||||
|
objectFit: 'cover',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Box sx={{ height: 160, display: 'flex', alignItems: 'center', justifyContent: 'center', bgcolor: 'grey.900' }}>
|
||||||
|
<CircularProgress size={32} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 12,
|
||||||
|
right: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StatusChip status={props.statusID}/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<CardContent sx={{
|
||||||
|
flex: 1,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
p: 2,
|
||||||
|
width: '100%',
|
||||||
|
}}>
|
||||||
|
<Box>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle1"
|
||||||
|
component="div"
|
||||||
|
sx={{
|
||||||
|
mb: 1,
|
||||||
|
fontWeight: 600,
|
||||||
|
color: '#fff',
|
||||||
|
lineHeight: '1.3',
|
||||||
|
// Allow text to wrap
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.displayName}
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
mb: 1.5,
|
||||||
|
}}>
|
||||||
|
<Explore sx={{
|
||||||
|
mr: 0.75,
|
||||||
|
mt: 0.25,
|
||||||
|
color: 'text.secondary',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
flexShrink: 0,
|
||||||
|
}} />
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 500,
|
||||||
|
// Allow text to wrap
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
lineHeight: '1.2',
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.gameID === 1 ? 'Bhop' : props.gameID === 2 ? 'Surf' : props.gameID === 5 ? 'Fly Trials' : props.gameID === 4 ? 'Deathrun' : 'Unknown'}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
mb: 1.5,
|
||||||
|
}}>
|
||||||
|
<Person2 sx={{
|
||||||
|
mr: 0.75,
|
||||||
|
mt: 0.25,
|
||||||
|
color: 'text.secondary',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
flexShrink: 0,
|
||||||
|
}} />
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
color="text.secondary"
|
||||||
|
sx={{
|
||||||
|
fontWeight: 500,
|
||||||
|
// Allow text to wrap
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
lineHeight: '1.2',
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.author}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Divider sx={{ my: 1.5 }} />
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Avatar
|
||||||
|
src={props.authorAvatarUrl}
|
||||||
|
alt={props.submitterUsername}
|
||||||
|
sx={{
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||||||
|
bgcolor: 'grey.900'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
sx={{
|
||||||
|
ml: 1,
|
||||||
|
color: 'text.secondary',
|
||||||
|
fontWeight: 500,
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.submitterUsername} - {new Date(props.created * 1000).toLocaleDateString('en-US', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
})}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</CardContent>
|
||||||
|
</CardActionArea>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
51
web/src/app/_components/review/CopyableField.tsx
Normal file
51
web/src/app/_components/review/CopyableField.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { Typography, Box, IconButton, Tooltip } from "@mui/material";
|
||||||
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
|
|
||||||
|
interface CopyableFieldProps {
|
||||||
|
label: string;
|
||||||
|
value: string | number | null | undefined;
|
||||||
|
onCopy: (value: string) => void;
|
||||||
|
placeholderText?: string;
|
||||||
|
link?: string; // Optional link prop
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CopyableField = ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
onCopy,
|
||||||
|
placeholderText = "Not assigned",
|
||||||
|
link
|
||||||
|
}: CopyableFieldProps) => {
|
||||||
|
const displayValue = value?.toString() || placeholderText;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Typography variant="body2" color="text.secondary">{label}</Typography>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
{link ? (
|
||||||
|
<a
|
||||||
|
href={link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
style={{ color: 'inherit', textDecoration: 'none', cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
<Typography variant="body1" sx={{ '&:hover': { textDecoration: 'underline' } }}>{displayValue}</Typography>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<Typography variant="body1">{displayValue}</Typography>
|
||||||
|
)}
|
||||||
|
{value && (
|
||||||
|
<Tooltip title="Copy ID">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => onCopy(value.toString())}
|
||||||
|
sx={{ ml: 1 }}
|
||||||
|
>
|
||||||
|
<ContentCopyIcon fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
155
web/src/app/_components/review/ReviewButtons.tsx
Normal file
155
web/src/app/_components/review/ReviewButtons.tsx
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Button, Stack } from '@mui/material';
|
||||||
|
import {MapfixInfo } from "@/app/ts/Mapfix";
|
||||||
|
import {hasRole, Roles, RolesConstants} from "@/app/ts/Roles";
|
||||||
|
import {SubmissionInfo} from "@/app/ts/Submission";
|
||||||
|
import {Status, StatusMatches} from "@/app/ts/Status";
|
||||||
|
|
||||||
|
interface ReviewAction {
|
||||||
|
name: string,
|
||||||
|
action: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReviewButtonsProps {
|
||||||
|
onClick: (action: string, id: number) => void;
|
||||||
|
item: (SubmissionInfo | MapfixInfo);
|
||||||
|
userId: number | null;
|
||||||
|
roles: Roles;
|
||||||
|
type: "submission" | "mapfix";
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReviewActions = {
|
||||||
|
Submit: {name:"Submit",action:"trigger-submit"} as ReviewAction,
|
||||||
|
SubmitUnchecked: {name:"Submit Unchecked", action:"trigger-submit-unchecked"} as ReviewAction,
|
||||||
|
ResetSubmitting: {name:"Reset Submitting",action:"reset-submitting"} as ReviewAction,
|
||||||
|
Revoke: {name:"Revoke",action:"revoke"} as ReviewAction,
|
||||||
|
Accept: {name:"Accept",action:"trigger-validate"} as ReviewAction,
|
||||||
|
Reject: {name:"Reject",action:"reject"} as ReviewAction,
|
||||||
|
Validate: {name:"Validate",action:"retry-validate"} as ReviewAction,
|
||||||
|
ResetValidating: {name:"Reset Validating",action:"reset-validating"} as ReviewAction,
|
||||||
|
RequestChanges: {name:"Request Changes",action:"request-changes"} as ReviewAction,
|
||||||
|
Upload: {name:"Upload",action:"trigger-upload"} as ReviewAction,
|
||||||
|
ResetUploading: {name:"Reset Uploading",action:"reset-uploading"} as ReviewAction,
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReviewButtons: React.FC<ReviewButtonsProps> = ({
|
||||||
|
onClick,
|
||||||
|
item,
|
||||||
|
userId,
|
||||||
|
roles,
|
||||||
|
type,
|
||||||
|
}) => {
|
||||||
|
const getVisibleButtons = () => {
|
||||||
|
if (!item || userId === null) return [];
|
||||||
|
|
||||||
|
// Define a type for the button
|
||||||
|
type ReviewButton = {
|
||||||
|
action: ReviewAction;
|
||||||
|
color: "primary" | "error" | "success" | "info" | "warning";
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttons: ReviewButton[] = [];
|
||||||
|
const is_submitter = userId === item.Submitter;
|
||||||
|
const status = item.StatusID;
|
||||||
|
|
||||||
|
const reviewRole = type === "submission" ? RolesConstants.SubmissionReview : RolesConstants.MapfixReview;
|
||||||
|
const uploadRole = type === "submission" ? RolesConstants.SubmissionUpload : RolesConstants.MapfixUpload;
|
||||||
|
|
||||||
|
if (is_submitter) {
|
||||||
|
if (StatusMatches(status, [Status.UnderConstruction, Status.ChangesRequested])) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.Submit,
|
||||||
|
color: "primary"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StatusMatches(status, [Status.Submitted, Status.ChangesRequested])) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.Revoke,
|
||||||
|
color: "error"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buttons for review role
|
||||||
|
if (hasRole(roles, reviewRole)) {
|
||||||
|
if (status === Status.Submitted && !is_submitter) {
|
||||||
|
buttons.push(
|
||||||
|
{
|
||||||
|
action: ReviewActions.Accept,
|
||||||
|
color: "success"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: ReviewActions.Reject,
|
||||||
|
color: "error"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === Status.AcceptedUnvalidated) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.Validate,
|
||||||
|
color: "info"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === Status.Validating) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.ResetValidating,
|
||||||
|
color: "warning"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StatusMatches(status, [Status.Validated, Status.AcceptedUnvalidated, Status.Submitted]) && !is_submitter) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.RequestChanges,
|
||||||
|
color: "warning"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === Status.ChangesRequested) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.SubmitUnchecked,
|
||||||
|
color: "warning"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buttons for upload role
|
||||||
|
if (hasRole(roles, uploadRole)) {
|
||||||
|
if (status === Status.Validated) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.Upload,
|
||||||
|
color: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === Status.Uploading) {
|
||||||
|
buttons.push({
|
||||||
|
action: ReviewActions.ResetUploading,
|
||||||
|
color: "warning"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack spacing={2} sx={{ mb: 3 }}>
|
||||||
|
{getVisibleButtons().map((button, index) => (
|
||||||
|
<Button
|
||||||
|
key={index}
|
||||||
|
variant="contained"
|
||||||
|
color={button.color}
|
||||||
|
fullWidth
|
||||||
|
onClick={() => onClick(button.action.action, item.ID)}
|
||||||
|
>
|
||||||
|
{button.action.name}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReviewButtons;
|
||||||
97
web/src/app/_components/review/ReviewItem.tsx
Normal file
97
web/src/app/_components/review/ReviewItem.tsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { Paper, Grid, Typography } from "@mui/material";
|
||||||
|
import { ReviewItemHeader } from "./ReviewItemHeader";
|
||||||
|
import { CopyableField } from "@/app/_components/review/CopyableField";
|
||||||
|
import { SubmissionInfo } from "@/app/ts/Submission";
|
||||||
|
import { MapfixInfo } from "@/app/ts/Mapfix";
|
||||||
|
|
||||||
|
// Define a field configuration for specific types
|
||||||
|
interface FieldConfig {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReviewItemType = SubmissionInfo | MapfixInfo;
|
||||||
|
|
||||||
|
interface ReviewItemProps {
|
||||||
|
item: ReviewItemType;
|
||||||
|
handleCopyValue: (value: string) => void;
|
||||||
|
submitterAvatarUrl?: string;
|
||||||
|
submitterUsername?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ReviewItem({
|
||||||
|
item,
|
||||||
|
handleCopyValue,
|
||||||
|
submitterAvatarUrl,
|
||||||
|
submitterUsername
|
||||||
|
}: ReviewItemProps) {
|
||||||
|
if (!item) return null;
|
||||||
|
|
||||||
|
// Determine the type of item
|
||||||
|
const isSubmission = 'UploadedAssetID' in item;
|
||||||
|
const isMapfix = 'TargetAssetID' in item;
|
||||||
|
|
||||||
|
// Define static fields based on item type
|
||||||
|
let fields: FieldConfig[] = [];
|
||||||
|
if (isSubmission) {
|
||||||
|
// Fields for Submission
|
||||||
|
fields = [
|
||||||
|
{ key: 'AssetID', label: 'Asset ID' },
|
||||||
|
{ key: 'UploadedAssetID', label: 'Uploaded Asset ID' },
|
||||||
|
];
|
||||||
|
} else if (isMapfix) {
|
||||||
|
// Fields for Mapfix
|
||||||
|
fields = [
|
||||||
|
{ key: 'AssetID', label: 'Asset ID' },
|
||||||
|
{ key: 'TargetAssetID', label: 'Target Asset ID' },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper elevation={3} sx={{ p: 3, borderRadius: 2, mb: 4 }}>
|
||||||
|
<ReviewItemHeader
|
||||||
|
displayName={item.DisplayName}
|
||||||
|
assetId={isMapfix ? item.TargetAssetID : undefined}
|
||||||
|
statusId={item.StatusID}
|
||||||
|
creator={item.Creator}
|
||||||
|
submitterId={item.Submitter}
|
||||||
|
submitterAvatarUrl={submitterAvatarUrl}
|
||||||
|
submitterUsername={submitterUsername}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Item Details */}
|
||||||
|
<Grid container spacing={2} sx={{ mt: 2 }}>
|
||||||
|
{fields.map((field) => {
|
||||||
|
const fieldValue = (item as never)[field.key];
|
||||||
|
const displayValue = fieldValue === 0 || fieldValue == null ? 'N/A' : fieldValue;
|
||||||
|
const isAssetId = field.key.includes('AssetID') && fieldValue !== 0 && fieldValue != null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid item xs={12} sm={6} key={field.key}>
|
||||||
|
<CopyableField
|
||||||
|
label={field.label}
|
||||||
|
value={String(displayValue)}
|
||||||
|
onCopy={handleCopyValue}
|
||||||
|
placeholderText={field.placeholder}
|
||||||
|
link={isAssetId ? `https://create.roblox.com/store/asset/${fieldValue}` : undefined}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Description Section */}
|
||||||
|
{isMapfix && item.Description && (
|
||||||
|
<div style={{ marginTop: 24 }}>
|
||||||
|
<Typography variant="subtitle1" fontWeight="bold" gutterBottom>
|
||||||
|
Description
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1">
|
||||||
|
{item.Description}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
97
web/src/app/_components/review/ReviewItemHeader.tsx
Normal file
97
web/src/app/_components/review/ReviewItemHeader.tsx
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import {Typography, Box, Avatar, keyframes} from "@mui/material";
|
||||||
|
import { StatusChip } from "@/app/_components/statusChip";
|
||||||
|
import { SubmissionStatus } from "@/app/ts/Submission";
|
||||||
|
import { MapfixStatus } from "@/app/ts/Mapfix";
|
||||||
|
import {Status, StatusMatches} from "@/app/ts/Status";
|
||||||
|
import Link from "next/link";
|
||||||
|
import LaunchIcon from '@mui/icons-material/Launch';
|
||||||
|
|
||||||
|
interface ReviewItemHeaderProps {
|
||||||
|
displayName: string;
|
||||||
|
assetId: number | null | undefined,
|
||||||
|
statusId: SubmissionStatus | MapfixStatus;
|
||||||
|
creator: string | null | undefined;
|
||||||
|
submitterId: number;
|
||||||
|
submitterAvatarUrl?: string;
|
||||||
|
submitterUsername?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ReviewItemHeader = ({ displayName, assetId, statusId, creator, submitterId, submitterAvatarUrl, submitterUsername }: ReviewItemHeaderProps) => {
|
||||||
|
const isProcessing = StatusMatches(statusId, [Status.Validating, Status.Uploading, Status.Submitting]);
|
||||||
|
const pulse = keyframes`
|
||||||
|
0%, 100% { opacity: 0.2; transform: scale(0.8); }
|
||||||
|
50% { opacity: 1; transform: scale(1); }
|
||||||
|
`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
|
||||||
|
{assetId != null ? (
|
||||||
|
<Link href={`/maps/${assetId}`} passHref legacyBehavior>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }} title="View related map">
|
||||||
|
<Typography
|
||||||
|
variant="h4"
|
||||||
|
component="h1"
|
||||||
|
gutterBottom
|
||||||
|
sx={{ color: 'inherit', textDecoration: 'none', mr: 1 }}
|
||||||
|
>
|
||||||
|
{displayName} by {creator}
|
||||||
|
</Typography>
|
||||||
|
<LaunchIcon sx={{ fontSize: '1.5rem', color: 'text.secondary' }} />
|
||||||
|
</Box>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Typography
|
||||||
|
variant="h4"
|
||||||
|
component="h1"
|
||||||
|
gutterBottom
|
||||||
|
sx={{ color: 'inherit', textDecoration: 'none', mr: 1 }}
|
||||||
|
>
|
||||||
|
{displayName} by {creator}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
{isProcessing && (
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: 0.5,
|
||||||
|
mr: 0.5,
|
||||||
|
height: 24
|
||||||
|
}}>
|
||||||
|
{[0, 1, 2].map((i) => (
|
||||||
|
<Box
|
||||||
|
key={i}
|
||||||
|
sx={{
|
||||||
|
width: 6,
|
||||||
|
height: 6,
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: 'primary.main',
|
||||||
|
animation: `${pulse} 1.4s ease-in-out infinite`,
|
||||||
|
animationDelay: `${i * 0.2}s`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<StatusChip status={statusId as number} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
|
||||||
|
<Avatar
|
||||||
|
src={submitterAvatarUrl}
|
||||||
|
sx={{ mr: 1, width: 24, height: 24, border: '1px solid rgba(255, 255, 255, 0.1)', bgcolor: 'grey.900' }}
|
||||||
|
/>
|
||||||
|
<Link href={`https://www.roblox.com/users/${submitterId}/profile`} target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none', color: 'inherit' }}>
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, '&:hover': { textDecoration: 'underline' } }}>
|
||||||
|
<Typography>
|
||||||
|
{submitterUsername ? `@${submitterUsername}` : submitterId}
|
||||||
|
</Typography>
|
||||||
|
<LaunchIcon sx={{ fontSize: '1rem', color: 'text.secondary' }} />
|
||||||
|
</Box>
|
||||||
|
</Link>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
87
web/src/app/_components/statusChip.tsx
Normal file
87
web/src/app/_components/statusChip.tsx
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import React, {JSX} from "react";
|
||||||
|
import {Cancel, CheckCircle, Pending} from "@mui/icons-material";
|
||||||
|
import {Chip} from "@mui/material";
|
||||||
|
|
||||||
|
export const StatusChip = ({status}: { status: number }) => {
|
||||||
|
let color: 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' = 'default';
|
||||||
|
let icon: JSX.Element = <Pending fontSize="small"/>;
|
||||||
|
let label: string = 'Unknown';
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
color = 'warning';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Under Construction';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
color = 'warning';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Changes Requested';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = 'info';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Submitting';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
color = 'warning';
|
||||||
|
icon = <CheckCircle fontSize="small"/>;
|
||||||
|
label = 'Under Review';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = 'warning';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Script Review';
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
color = 'info';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Validating';
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
color = 'success';
|
||||||
|
icon = <CheckCircle fontSize="small"/>;
|
||||||
|
label = 'Validated';
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
color = 'info';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Uploading';
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
color = 'success';
|
||||||
|
icon = <CheckCircle fontSize="small"/>;
|
||||||
|
label = 'Uploaded';
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
color = 'error';
|
||||||
|
icon = <Cancel fontSize="small"/>;
|
||||||
|
label = 'Rejected';
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
color = 'success';
|
||||||
|
icon = <CheckCircle fontSize="small"/>;
|
||||||
|
label = 'Released';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = 'default';
|
||||||
|
icon = <Pending fontSize="small"/>;
|
||||||
|
label = 'Unknown';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Chip
|
||||||
|
icon={icon}
|
||||||
|
label={label}
|
||||||
|
color={color}
|
||||||
|
size="small"
|
||||||
|
sx={{
|
||||||
|
height: 24,
|
||||||
|
fontSize: '0.75rem',
|
||||||
|
fontWeight: 600,
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -3,8 +3,10 @@
|
|||||||
import Header from "./header";
|
import Header from "./header";
|
||||||
|
|
||||||
export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) {
|
export default function Webpage({children}: Readonly<{children?: React.ReactNode}>) {
|
||||||
return <>
|
return (
|
||||||
<Header/>
|
<>
|
||||||
{children}
|
<Header />
|
||||||
</>
|
{children}
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import GameSelection from "./_game";
|
|||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
import Webpage from "@/app/_components/webpage"
|
import Webpage from "@/app/_components/webpage"
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import {useTitle} from "@/app/hooks/useTitle";
|
||||||
|
|
||||||
import "./(styles)/page.scss"
|
import "./(styles)/page.scss"
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@ interface IdResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function SubmissionInfoPage() {
|
export default function SubmissionInfoPage() {
|
||||||
|
useTitle("Admin Submit");
|
||||||
|
|
||||||
const [game, setGame] = useState(1);
|
const [game, setGame] = useState(1);
|
||||||
|
|
||||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
|||||||
61
web/src/app/hooks/useBatchThumbnails.ts
Normal file
61
web/src/app/hooks/useBatchThumbnails.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
function chunkArray<T>(arr: T[], size: number): T[][] {
|
||||||
|
const res: T[][] = [];
|
||||||
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
|
res.push(arr.slice(i, i + size));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches thumbnail URLs for a batch of asset IDs using the unified /thumbnails/batch endpoint.
|
||||||
|
* Handles loading and error state. Returns a mapping of assetId to URL.
|
||||||
|
*/
|
||||||
|
export function useBatchThumbnails(assetIds: (number | string)[] | undefined) {
|
||||||
|
const [thumbnails, setThumbnails] = useState<Record<number, string>>({});
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!assetIds || assetIds.length === 0) {
|
||||||
|
setThumbnails({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const filteredIds = assetIds.filter(Boolean);
|
||||||
|
if (filteredIds.length === 0) {
|
||||||
|
setThumbnails({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
const chunks = chunkArray(filteredIds, 50);
|
||||||
|
Promise.all(
|
||||||
|
chunks.map(chunk =>
|
||||||
|
fetch(`/thumbnails/batch?type=asset&ids=${chunk.join(",")}&type=asset`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch thumbnails: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(datas => {
|
||||||
|
const result: Record<number, string> = {};
|
||||||
|
for (const data of datas) {
|
||||||
|
for (const [id, url] of Object.entries(data)) {
|
||||||
|
if (url) result[Number(id)] = url as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setThumbnails(result);
|
||||||
|
})
|
||||||
|
.catch(err => setError(err))
|
||||||
|
.finally(() => setLoading(false));
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [assetIds && assetIds.filter(Boolean).join(",")]);
|
||||||
|
|
||||||
|
return { thumbnails, loading, error };
|
||||||
|
}
|
||||||
61
web/src/app/hooks/useBatchUserAvatars.ts
Normal file
61
web/src/app/hooks/useBatchUserAvatars.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
function chunkArray<T>(arr: T[], size: number): T[][] {
|
||||||
|
const res: T[][] = [];
|
||||||
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
|
res.push(arr.slice(i, i + size));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches avatar URLs for a batch of user IDs using the unified /thumbnails/batch?type=user endpoint.
|
||||||
|
* Returns a mapping of userId to avatar URL.
|
||||||
|
*/
|
||||||
|
export function useBatchUserAvatars(userIds: (number | string)[] | undefined) {
|
||||||
|
const [avatars, setAvatars] = useState<Record<number, string>>({});
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!userIds || userIds.length === 0) {
|
||||||
|
setAvatars({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const filteredIds = userIds.filter(Boolean);
|
||||||
|
if (filteredIds.length === 0) {
|
||||||
|
setAvatars({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
const chunks = chunkArray(filteredIds, 50);
|
||||||
|
Promise.all(
|
||||||
|
chunks.map(chunk =>
|
||||||
|
fetch(`/thumbnails/batch?type=user&ids=${chunk.join(",")}`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch user avatars: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(datas => {
|
||||||
|
const result: Record<number, string> = {};
|
||||||
|
for (const data of datas) {
|
||||||
|
for (const [id, url] of Object.entries(data)) {
|
||||||
|
if (url) result[Number(id)] = url as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setAvatars(result);
|
||||||
|
})
|
||||||
|
.catch(err => setError(err))
|
||||||
|
.finally(() => setLoading(false));
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [userIds && userIds.filter(Boolean).join(",")]);
|
||||||
|
|
||||||
|
return { avatars, loading, error };
|
||||||
|
}
|
||||||
63
web/src/app/hooks/useBatchUsernames.ts
Normal file
63
web/src/app/hooks/useBatchUsernames.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
function chunkArray<T>(arr: T[], size: number): T[][] {
|
||||||
|
const res: T[][] = [];
|
||||||
|
for (let i = 0; i < arr.length; i += size) {
|
||||||
|
res.push(arr.slice(i, i + size));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches usernames for a batch of user IDs using the /proxy/users/batch?ids=... endpoint.
|
||||||
|
* Returns a mapping of userId to username (or userId as string if not found).
|
||||||
|
*/
|
||||||
|
export function useBatchUsernames(userIds: (number | string)[] | undefined) {
|
||||||
|
const [usernames, setUsernames] = useState<Record<number, string>>({});
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!userIds || userIds.length === 0) {
|
||||||
|
setUsernames({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const filteredIds = userIds.filter(Boolean);
|
||||||
|
if (filteredIds.length === 0) {
|
||||||
|
setUsernames({});
|
||||||
|
setLoading(false);
|
||||||
|
setError(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
const chunks = chunkArray(filteredIds, 50);
|
||||||
|
Promise.all(
|
||||||
|
chunks.map(chunk =>
|
||||||
|
fetch(`/proxy/users/batch?ids=${chunk.join(",")}`)
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch usernames: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(datas => {
|
||||||
|
const result: Record<number, string> = {};
|
||||||
|
for (const data of datas) {
|
||||||
|
if (Array.isArray(data.data)) {
|
||||||
|
for (const user of data.data) {
|
||||||
|
result[user.id] = user.name || String(user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setUsernames(result);
|
||||||
|
})
|
||||||
|
.catch(err => setError(err))
|
||||||
|
.finally(() => setLoading(false));
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [userIds && userIds.filter(Boolean).join(",")]);
|
||||||
|
|
||||||
|
return { usernames, loading, error };
|
||||||
|
}
|
||||||
122
web/src/app/hooks/useReviewData.ts
Normal file
122
web/src/app/hooks/useReviewData.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import {useState, useEffect, useCallback} from "react";
|
||||||
|
import {Roles, RolesConstants} from "@/app/ts/Roles";
|
||||||
|
import {AuditEvent} from "@/app/ts/AuditEvent";
|
||||||
|
import {Status, StatusMatches} from "@/app/ts/Status";
|
||||||
|
import {MapfixInfo} from "@/app/ts/Mapfix";
|
||||||
|
import {SubmissionInfo} from "@/app/ts/Submission";
|
||||||
|
|
||||||
|
type ReviewItemType = "submissions" | "mapfixes";
|
||||||
|
type ReviewData = MapfixInfo | SubmissionInfo;
|
||||||
|
|
||||||
|
interface UseReviewDataProps {
|
||||||
|
itemType: ReviewItemType;
|
||||||
|
itemId: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UseReviewDataResult {
|
||||||
|
data: ReviewData | null;
|
||||||
|
auditEvents: AuditEvent[];
|
||||||
|
roles: Roles;
|
||||||
|
user: number | null;
|
||||||
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
refreshData: (skipLoadingState?: boolean) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useReviewData({itemType, itemId}: UseReviewDataProps): UseReviewDataResult {
|
||||||
|
const [data, setData] = useState<ReviewData | null>(null);
|
||||||
|
const [auditEvents, setAuditEvents] = useState<AuditEvent[]>([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const [user, setUser] = useState<number | null>(null);
|
||||||
|
const [roles, setRoles] = useState<Roles>(RolesConstants.Empty);
|
||||||
|
|
||||||
|
const fetchData = useCallback(async (skipLoadingState = false) => {
|
||||||
|
try {
|
||||||
|
if (!skipLoadingState) {
|
||||||
|
setLoading(true);
|
||||||
|
}
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [reviewData, auditData] = await Promise.all([
|
||||||
|
fetch(`/api/${itemType}/${itemId}`).then(res => {
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch ${itemType.slice(0, -1)}: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
}),
|
||||||
|
fetch(`/api/${itemType}/${itemId}/audit-events?Page=1&Limit=100`).then(res => {
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch audit events: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
setData(reviewData);
|
||||||
|
setAuditEvents(auditData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching critical ${itemType} data:`, error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rolesResponse = await fetch("/api/session/roles");
|
||||||
|
if (rolesResponse.ok) {
|
||||||
|
const rolesData = await rolesResponse.json();
|
||||||
|
setRoles(rolesData.Roles);
|
||||||
|
} else {
|
||||||
|
console.warn(`Failed to fetch roles: ${rolesResponse.status}`);
|
||||||
|
setRoles(RolesConstants.Empty);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Error fetching roles data:", error);
|
||||||
|
setRoles(RolesConstants.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userResponse = await fetch("/api/session/user");
|
||||||
|
if (userResponse.ok) {
|
||||||
|
const userData = await userResponse.json();
|
||||||
|
setUser(userData.UserID);
|
||||||
|
} else {
|
||||||
|
console.warn(`Failed to fetch user: ${userResponse.status}`);
|
||||||
|
setUser(null);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Error fetching user data:", error);
|
||||||
|
setUser(null);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching review data:", error);
|
||||||
|
setError(error instanceof Error ? error.message : `Failed to load ${itemType.slice(0, -1)} details`);
|
||||||
|
} finally {
|
||||||
|
if (!skipLoadingState) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [itemId, itemType]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchData();
|
||||||
|
}, [fetchData]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data) {
|
||||||
|
if (StatusMatches(data.StatusID, [Status.Uploading, Status.Submitting, Status.Validating])) {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
fetchData(true);
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [data, itemType, fetchData]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
auditEvents,
|
||||||
|
roles,
|
||||||
|
user,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
refreshData: fetchData
|
||||||
|
};
|
||||||
|
}
|
||||||
9
web/src/app/hooks/useTitle.ts
Normal file
9
web/src/app/hooks/useTitle.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
export function useTitle(title: string) {
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = `${title} | StrafesNET`;
|
||||||
|
}, [title]);
|
||||||
|
}
|
||||||
@@ -1,9 +1,26 @@
|
|||||||
import "./globals.scss";
|
import "./globals.scss";
|
||||||
|
import { SWRConfig } from "swr";
|
||||||
|
import { getSessionUser, getSessionRoles } from "@/app/lib/session";
|
||||||
|
import AppProviders from "@/app/_components/AppProviders";
|
||||||
|
|
||||||
|
export default async function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||||
|
const user = await getSessionUser();
|
||||||
|
const roles = await getSessionRoles();
|
||||||
|
|
||||||
export default function RootLayout({children}: Readonly<{children: React.ReactNode}>) {
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body>{children}</body>
|
<body>
|
||||||
|
<SWRConfig value={{
|
||||||
|
fallback: {
|
||||||
|
"/api/session/user": user,
|
||||||
|
"/api/session/roles": { Roles: roles }
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<AppProviders>
|
||||||
|
{children}
|
||||||
|
</AppProviders>
|
||||||
|
</SWRConfig>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
26
web/src/app/lib/session.ts
Normal file
26
web/src/app/lib/session.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
|
const BASE_URL = process.env.API_HOST;
|
||||||
|
|
||||||
|
export async function getSessionUser() {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const cookieHeader = cookieStore.toString();
|
||||||
|
const res = await fetch(`${BASE_URL}/session/user`, {
|
||||||
|
headers: { Cookie: cookieHeader },
|
||||||
|
cache: 'no-store',
|
||||||
|
});
|
||||||
|
if (!res.ok) return null;
|
||||||
|
return await res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSessionRoles() {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const cookieHeader = cookieStore.toString();
|
||||||
|
const res = await fetch(`${BASE_URL}/session/roles`, {
|
||||||
|
headers: { Cookie: cookieHeader },
|
||||||
|
cache: 'no-store',
|
||||||
|
});
|
||||||
|
if (!res.ok) return 0;
|
||||||
|
const data = await res.json();
|
||||||
|
return data.Roles ?? 0;
|
||||||
|
}
|
||||||
91
web/src/app/lib/theme.tsx
Normal file
91
web/src/app/lib/theme.tsx
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import {createTheme} from "@mui/material";
|
||||||
|
|
||||||
|
export const theme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'dark',
|
||||||
|
primary: {
|
||||||
|
main: '#90caf9',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: '#f48fb1',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: '#121212',
|
||||||
|
paper: '#1e1e1e',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typography: {
|
||||||
|
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
|
||||||
|
h5: {
|
||||||
|
fontWeight: 500,
|
||||||
|
letterSpacing: '0.5px',
|
||||||
|
},
|
||||||
|
subtitle1: {
|
||||||
|
fontWeight: 500,
|
||||||
|
fontSize: '0.95rem',
|
||||||
|
},
|
||||||
|
body2: {
|
||||||
|
fontSize: '0.875rem',
|
||||||
|
},
|
||||||
|
caption: {
|
||||||
|
fontSize: '0.75rem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
borderRadius: 8,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
MuiCard: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
borderRadius: 8,
|
||||||
|
overflow: 'hidden',
|
||||||
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
||||||
|
transition: 'transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out',
|
||||||
|
'&:hover': {
|
||||||
|
transform: 'translateY(-4px)',
|
||||||
|
boxShadow: '0 8px 16px rgba(0, 0, 0, 0.2)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiCardMedia: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiCardContent: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
padding: 16,
|
||||||
|
'&:last-child': {
|
||||||
|
paddingBottom: 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiChip: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
fontWeight: 500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiDivider: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MuiPaper: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
backgroundImage: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
@forward "../../_components/styles/mapCard.scss";
|
|
||||||
|
|
||||||
@use "../../globals.scss";
|
|
||||||
|
|
||||||
a {
|
|
||||||
color:rgb(255, 255, 255);
|
|
||||||
|
|
||||||
&:visited, &:hover, &:focus {
|
|
||||||
text-decoration: none;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
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,19 +0,0 @@
|
|||||||
@forward "./page/commentWindow.scss";
|
|
||||||
@forward "./page/reviewStatus.scss";
|
|
||||||
@forward "./page/ratingWindow.scss";
|
|
||||||
@forward "./page/reviewButtons.scss";
|
|
||||||
@forward "./page/comments.scss";
|
|
||||||
@forward "./page/review.scss";
|
|
||||||
@forward "./page/map.scss";
|
|
||||||
|
|
||||||
@use "../../../globals.scss";
|
|
||||||
|
|
||||||
.map-page-main {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.by-creator {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
@use "../../../../globals.scss";
|
|
||||||
|
|
||||||
#comment-text-field {
|
|
||||||
@include globals.border-with-radius;
|
|
||||||
resize: none;
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
background-color: var(--comment-area)
|
|
||||||
}
|
|
||||||
|
|
||||||
.leave-comment-window {
|
|
||||||
@include globals.border-with-radius;
|
|
||||||
width: 100%;
|
|
||||||
height: 230px;
|
|
||||||
margin-top: 35px;
|
|
||||||
|
|
||||||
.rating-type {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
gap: 35%;
|
|
||||||
|
|
||||||
.rating-right {
|
|
||||||
display: grid;
|
|
||||||
|
|
||||||
> span {
|
|
||||||
margin: 6px 0 6px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 15px 0 15px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: var(--window-header);
|
|
||||||
border-bottom: globals.$review-border;
|
|
||||||
height: 45px;
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 0 0 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin-top: 9px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
$comments-size: 60px;
|
|
||||||
|
|
||||||
.comments {
|
|
||||||
display: grid;
|
|
||||||
gap: 25px;
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
.no-comments {
|
|
||||||
text-align: center;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commenter {
|
|
||||||
display: flex;
|
|
||||||
height: $comments-size;
|
|
||||||
|
|
||||||
//BhopMaptest comment
|
|
||||||
&[data-highlighted="true"] {
|
|
||||||
background-color: var(--comment-highlighted);
|
|
||||||
}
|
|
||||||
> img {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font: {
|
|
||||||
weight: 500;
|
|
||||||
size: 1.3em;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
.date {
|
|
||||||
font-size: .8em;
|
|
||||||
margin: 0 0 0 5px;
|
|
||||||
color: #646464
|
|
||||||
}
|
|
||||||
.details {
|
|
||||||
display: grid;
|
|
||||||
margin-left: 10px;
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
p:not(.date) {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
@use "../../../../globals.scss";
|
|
||||||
|
|
||||||
.map-image-area {
|
|
||||||
@include globals.border-with-radius;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 350px;
|
|
||||||
height: 350px;
|
|
||||||
|
|
||||||
> p {
|
|
||||||
text-align: center;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
@use "../../../../globals.scss";
|
|
||||||
|
|
||||||
.rating-window {
|
|
||||||
@include globals.border-with-radius;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.rating-type {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
gap: 35%;
|
|
||||||
|
|
||||||
.rating-right {
|
|
||||||
display: grid;
|
|
||||||
|
|
||||||
> span {
|
|
||||||
margin: 6px 0 6px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 15px 0 15px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: var(--window-header);
|
|
||||||
border-bottom: globals.$review-border;
|
|
||||||
height: 45px;
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0 0 0 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
@use "../../../../globals.scss";
|
|
||||||
|
|
||||||
.review-info {
|
|
||||||
width: 650px;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
> div {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
p, h1 {
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font: {
|
|
||||||
weight: 500;
|
|
||||||
size: 1.8rem
|
|
||||||
};
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: var(--anchor-link-review);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-section {
|
|
||||||
display: flex;
|
|
||||||
gap: 50px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.review-area {
|
|
||||||
display: grid;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 25px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 350px;
|
|
||||||
object-fit: contain
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
@use "../../../../globals.scss";
|
|
||||||
|
|
||||||
.review-set {
|
|
||||||
@include globals.border-with-radius;
|
|
||||||
display: grid;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
$UnderConstruction: "0";
|
|
||||||
$Submitted: "1";
|
|
||||||
$ChangesRequested: "2";
|
|
||||||
$Accepted: "3";
|
|
||||||
$Validating: "4";
|
|
||||||
$Validated: "5";
|
|
||||||
$Uploading: "6";
|
|
||||||
$Uploaded: "7";
|
|
||||||
$Rejected: "8";
|
|
||||||
$Released: "9";
|
|
||||||
|
|
||||||
.review-status {
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 3px 25px 3px 25px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-review-status="#{$Released}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Rejected}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Uploading}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Uploaded}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Validated}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Validating}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Accepted}"] {
|
|
||||||
background-color: rgb(2, 162, 2);
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$ChangesRequested}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$Submitted}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&[data-review-status="#{$UnderConstruction}"] {
|
|
||||||
background-color: orange;
|
|
||||||
p {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
import type { MapfixInfo } from "@/app/ts/Mapfix";
|
|
||||||
import { Button } from "@mui/material"
|
|
||||||
import Window from "./_window";
|
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
|
||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
interface CommentersProps {
|
|
||||||
comments_data: CreatorAndReviewStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CreatorAndReviewStatus {
|
|
||||||
asset_id: MapfixInfo["AssetID"],
|
|
||||||
creator: MapfixInfo["DisplayName"],
|
|
||||||
review: MapfixInfo["StatusID"],
|
|
||||||
submitter: MapfixInfo["Submitter"],
|
|
||||||
target_asset_id: MapfixInfo["TargetAssetID"],
|
|
||||||
description: MapfixInfo["Description"],
|
|
||||||
comments: Comment[],
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Comment {
|
|
||||||
picture?: string, //TEMP
|
|
||||||
comment: string,
|
|
||||||
date: string,
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddComment(comment: Comment) {
|
|
||||||
const IsBhopMaptest = comment.name == "BhopMaptest" //Highlighted commenter
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="commenter" data-highlighted={IsBhopMaptest}>
|
|
||||||
<Image src={comment.picture as string} alt={`${comment.name}'s comment`}/>
|
|
||||||
<div className="details">
|
|
||||||
<header>
|
|
||||||
<p className="name">{comment.name}</p>
|
|
||||||
<p className="date">{comment.date}</p>
|
|
||||||
</header>
|
|
||||||
<p className="comment">{comment.comment}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function LeaveAComment() {
|
|
||||||
return (
|
|
||||||
<Window title="Leave a Comment:" className="leave-comment-window">
|
|
||||||
<textarea name="comment-box" id="comment-text-field"></textarea>
|
|
||||||
<Button variant="outlined" endIcon={<SendIcon/>}>Submit</Button>
|
|
||||||
</Window>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Comments(stats: CommentersProps) {
|
|
||||||
return (<>
|
|
||||||
<section className="comments">
|
|
||||||
{stats.comments_data.comments.length===0
|
|
||||||
&& <p className="no-comments">There are no comments.</p>
|
|
||||||
|| stats.comments_data.comments.map(comment => (
|
|
||||||
<AddComment key={comment.name} name={comment.name} date={comment.date} comment={comment.comment}/>
|
|
||||||
))}
|
|
||||||
</section>
|
|
||||||
<LeaveAComment/>
|
|
||||||
</>)
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
type CreatorAndReviewStatus,
|
|
||||||
type Comment,
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import Image from "next/image";
|
|
||||||
import { MapfixInfo } from "@/app/ts/Mapfix"
|
|
||||||
|
|
||||||
interface AssetID {
|
|
||||||
id: MapfixInfo["AssetID"]
|
|
||||||
}
|
|
||||||
|
|
||||||
function MapImage({ id }: AssetID) {
|
|
||||||
if (!id) {
|
|
||||||
return <p>Missing asset ID</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageUrl = `/thumbnails/asset/${id}`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Image
|
|
||||||
src={imageUrl}
|
|
||||||
alt="Map Thumbnail"
|
|
||||||
layout="responsive"
|
|
||||||
width={512}
|
|
||||||
height={512}
|
|
||||||
priority={true}
|
|
||||||
className="map-image"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
type AssetID,
|
|
||||||
MapImage
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user