Compare commits
1 Commits
int
...
restricted
| Author | SHA1 | Date | |
|---|---|---|---|
|
69438a9d0c
|
921
Cargo.lock
generated
921
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
# Stage 1: Build
|
# Stage 1: Build
|
||||||
FROM registry.itzana.me/docker-proxy/golang:1.24 AS builder
|
FROM docker.io/golang:1.23 AS builder
|
||||||
|
|
||||||
# Set the working directory in the container
|
# Set the working directory in the container
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
@@ -14,7 +14,7 @@ COPY . .
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux go build -o service ./cmd/maps-service/service.go
|
RUN CGO_ENABLED=0 GOOS=linux go build -o service ./cmd/maps-service/service.go
|
||||||
|
|
||||||
# Stage 2: Run
|
# Stage 2: Run
|
||||||
FROM registry.itzana.me/docker-proxy/alpine:3.21
|
FROM alpine
|
||||||
|
|
||||||
# Set up a non-root user for security
|
# Set up a non-root user for security
|
||||||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
||||||
|
|||||||
@@ -26,11 +26,10 @@ Prerequisite: golang installed
|
|||||||
|
|
||||||
Prerequisite: bun installed
|
Prerequisite: bun installed
|
||||||
|
|
||||||
The environment variables `API_HOST` and `AUTH_HOST` will need to be set for the middleware.
|
The environment variable `API_HOST` will need to be set for the middleware.
|
||||||
Example `.env` in web's root:
|
Example `.env` in web's root:
|
||||||
```
|
```
|
||||||
API_HOST="http://localhost:8082/"
|
API_HOST="http://localhost:8082/v1/"
|
||||||
AUTH_HOST="http://localhost:8083/"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
1. `cd web`
|
1. `cd web`
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ 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
|
||||||
@@ -52,7 +50,6 @@ services:
|
|||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
environment:
|
environment:
|
||||||
- API_HOST=http://submissions:8082/v1
|
- API_HOST=http://submissions:8082/v1
|
||||||
- AUTH_HOST=http://localhost:8080/
|
|
||||||
|
|
||||||
validation:
|
validation:
|
||||||
image:
|
image:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/api --clean openapi.yaml
|
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/api --clean openapi.yaml
|
||||||
|
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/internal --clean openapi-internal.yaml
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -5,7 +5,7 @@ go 1.22
|
|||||||
toolchain go1.23.3
|
toolchain go1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7
|
||||||
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9
|
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9
|
||||||
github.com/dchest/siphash v1.2.3
|
github.com/dchest/siphash v1.2.3
|
||||||
github.com/go-faster/errors v0.7.1
|
github.com/go-faster/errors v0.7.1
|
||||||
@@ -53,7 +53,7 @@ require (
|
|||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/segmentio/asm v1.2.0 // indirect
|
github.com/segmentio/asm v1.2.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.25.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,7 +1,7 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815 h1:hkuOnehphRXUq/2z2UYgoqTq5MJj1GsWfshyc7bXda8=
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7 h1:5XzWd3ZZjSw1M60IfHuILty2vRPBYiqM0FZ+E7uHCi8=
|
||||||
git.itzana.me/strafesnet/go-grpc v0.0.0-20250724030029-845bea991815/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
|
||||||
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 h1:7lU6jyR7S7Rhh1dnUp7GyIRHUTBXZagw8F4n4hOyxLw=
|
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 h1:7lU6jyR7S7Rhh1dnUp7GyIRHUTBXZagw8F4n4hOyxLw=
|
||||||
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9/go.mod h1:uyYerSieEt4v0MJCdPLppG0LtJ4Yj035vuTetWGsxjY=
|
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9/go.mod h1:uyYerSieEt4v0MJCdPLppG0LtJ4Yj035vuTetWGsxjY=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
|||||||
674
openapi-internal.yaml
Normal file
674
openapi-internal.yaml
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
openapi: 3.1.0
|
||||||
|
info:
|
||||||
|
title: StrafesNET Internal - OpenAPI 3.1
|
||||||
|
description: Internal operations inaccessible from the public internet.
|
||||||
|
version: 0.1.0
|
||||||
|
tags:
|
||||||
|
- name: Mapfixes
|
||||||
|
description: Mapfix operations
|
||||||
|
- name: Submissions
|
||||||
|
description: Submission operations
|
||||||
|
paths:
|
||||||
|
/mapfixes:
|
||||||
|
post:
|
||||||
|
summary: Create a mapfix
|
||||||
|
operationId: createMapfix
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/MapfixCreate'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/MapfixID"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/validated-model:
|
||||||
|
post:
|
||||||
|
summary: Update validated model
|
||||||
|
operationId: updateMapfixValidatedModel
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
- name: ValidatedModelID
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: ValidatedModelVersion
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/status/validator-validated:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
|
||||||
|
operationId: actionMapfixValidated
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/status/validator-failed:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
|
||||||
|
operationId: actionMapfixAccepted
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
- name: StatusMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/mapfixes/{MapfixID}/status/validator-uploaded:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
|
||||||
|
operationId: actionMapfixUploaded
|
||||||
|
tags:
|
||||||
|
- Mapfixes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/MapfixID'
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/operations/{OperationID}/status/operation-failed:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Fail an operation and write a StatusMessage
|
||||||
|
operationId: actionOperationFailed
|
||||||
|
tags:
|
||||||
|
- Operations
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/OperationID'
|
||||||
|
- name: StatusMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions:
|
||||||
|
post:
|
||||||
|
summary: Create a new submission
|
||||||
|
operationId: createSubmission
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SubmissionCreate'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/SubmissionID"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/validated-model:
|
||||||
|
post:
|
||||||
|
summary: Update validated model
|
||||||
|
operationId: updateSubmissionValidatedModel
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
- name: ValidatedModelID
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: ValidatedModelVersion
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/status/validator-validated:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
|
||||||
|
operationId: actionSubmissionValidated
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/status/validator-failed:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
|
||||||
|
operationId: actionSubmissionAccepted
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
- name: StatusMessage
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 0
|
||||||
|
maxLength: 4096
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/submissions/{SubmissionID}/status/validator-uploaded:
|
||||||
|
post:
|
||||||
|
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
|
||||||
|
operationId: actionSubmissionUploaded
|
||||||
|
tags:
|
||||||
|
- Submissions
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SubmissionID'
|
||||||
|
- name: UploadedAssetID
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: Successful response
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/script-policy:
|
||||||
|
get:
|
||||||
|
summary: Get list of script policies
|
||||||
|
operationId: listScriptPolicy
|
||||||
|
tags:
|
||||||
|
- ScriptPolicy
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/Page"
|
||||||
|
- $ref: "#/components/parameters/Limit"
|
||||||
|
- name: FromScriptHash
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 16
|
||||||
|
maxLength: 16
|
||||||
|
- name: ToScriptID
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: Policy
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/ScriptPolicy"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
post:
|
||||||
|
summary: Create a new script policy
|
||||||
|
operationId: createScriptPolicy
|
||||||
|
tags:
|
||||||
|
- ScriptPolicy
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ScriptPolicyCreate'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ScriptPolicyID"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/scripts:
|
||||||
|
get:
|
||||||
|
summary: Get list of scripts
|
||||||
|
operationId: listScripts
|
||||||
|
tags:
|
||||||
|
- Script
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/Page"
|
||||||
|
- $ref: "#/components/parameters/Limit"
|
||||||
|
- name: Hash
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
minLength: 16
|
||||||
|
maxLength: 16
|
||||||
|
- name: Name
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
- name: Source
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
maxLength: 1048576
|
||||||
|
- name: ResourceType
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
- name: ResourceID
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Script"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
post:
|
||||||
|
summary: Create a new script
|
||||||
|
operationId: createScript
|
||||||
|
tags:
|
||||||
|
- Scripts
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ScriptCreate'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ScriptID"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
/scripts/{ScriptID}:
|
||||||
|
get:
|
||||||
|
summary: Get the specified script by ID
|
||||||
|
operationId: getScript
|
||||||
|
tags:
|
||||||
|
- Scripts
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ScriptID'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Successful response
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Script"
|
||||||
|
default:
|
||||||
|
description: General Error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Error"
|
||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
MapfixID:
|
||||||
|
name: MapfixID
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique identifier for a submission.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
OperationID:
|
||||||
|
name: OperationID
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique identifier for a long-running operation.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
SubmissionID:
|
||||||
|
name: SubmissionID
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique identifier for a submission.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ScriptID:
|
||||||
|
name: ScriptID
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique identifier for a script.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Page:
|
||||||
|
name: Page
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
Limit:
|
||||||
|
name: Limit
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
maximum: 100
|
||||||
|
schemas:
|
||||||
|
MapfixID:
|
||||||
|
required:
|
||||||
|
- MapfixID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
MapfixID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
SubmissionID:
|
||||||
|
required:
|
||||||
|
- SubmissionID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
SubmissionID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ScriptID:
|
||||||
|
required:
|
||||||
|
- ScriptID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ScriptID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ScriptPolicyID:
|
||||||
|
required:
|
||||||
|
- ScriptPolicyID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ScriptPolicyID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
MapfixCreate:
|
||||||
|
required:
|
||||||
|
- OperationID
|
||||||
|
- AssetOwner
|
||||||
|
- DisplayName
|
||||||
|
- Creator
|
||||||
|
- GameID
|
||||||
|
- AssetID
|
||||||
|
- AssetVersion
|
||||||
|
- TargetAssetID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
OperationID:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
AssetOwner:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
DisplayName:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
Creator:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
GameID:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
AssetID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
AssetVersion:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
TargetAssetID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
SubmissionCreate:
|
||||||
|
required:
|
||||||
|
- OperationID
|
||||||
|
- AssetOwner
|
||||||
|
- DisplayName
|
||||||
|
- Creator
|
||||||
|
- GameID
|
||||||
|
- AssetID
|
||||||
|
- AssetVersion
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
OperationID:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
AssetOwner:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
DisplayName:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
Creator:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
GameID:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
AssetID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
AssetVersion:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Script:
|
||||||
|
required:
|
||||||
|
- ID
|
||||||
|
- Name
|
||||||
|
- Hash
|
||||||
|
- Source
|
||||||
|
- ResourceType
|
||||||
|
- ResourceID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Name:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
Hash:
|
||||||
|
type: string
|
||||||
|
minLength: 16
|
||||||
|
maxLength: 16
|
||||||
|
Source:
|
||||||
|
type: string
|
||||||
|
maxLength: 1048576
|
||||||
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ScriptCreate:
|
||||||
|
required:
|
||||||
|
- Name
|
||||||
|
- Source
|
||||||
|
- ResourceType
|
||||||
|
# - ResourceID
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
Name:
|
||||||
|
type: string
|
||||||
|
maxLength: 128
|
||||||
|
Source:
|
||||||
|
type: string
|
||||||
|
maxLength: 1048576
|
||||||
|
ResourceType:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ResourceID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ScriptPolicy:
|
||||||
|
required:
|
||||||
|
- ID
|
||||||
|
- FromScriptHash
|
||||||
|
- ToScriptID
|
||||||
|
- Policy
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
ID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
FromScriptHash:
|
||||||
|
type: string
|
||||||
|
minLength: 16
|
||||||
|
maxLength: 16
|
||||||
|
ToScriptID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Policy:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
ScriptPolicyCreate:
|
||||||
|
required:
|
||||||
|
- FromScriptID
|
||||||
|
- ToScriptID
|
||||||
|
- Policy
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
FromScriptID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ToScriptID:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
Policy:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
Error:
|
||||||
|
description: Represents error object
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- code
|
||||||
|
- message
|
||||||
666
openapi.yaml
666
openapi.yaml
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,277 +13,6 @@ import (
|
|||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
|
||||||
func (s *AuditEvent) Encode(e *jx.Encoder) {
|
|
||||||
e.ObjStart()
|
|
||||||
s.encodeFields(e)
|
|
||||||
e.ObjEnd()
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeFields encodes fields.
|
|
||||||
func (s *AuditEvent) encodeFields(e *jx.Encoder) {
|
|
||||||
{
|
|
||||||
e.FieldStart("ID")
|
|
||||||
e.Int64(s.ID)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("Date")
|
|
||||||
e.Int64(s.Date)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("User")
|
|
||||||
e.Int64(s.User)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("Username")
|
|
||||||
e.Str(s.Username)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("ResourceType")
|
|
||||||
e.Int32(s.ResourceType)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("ResourceID")
|
|
||||||
e.Int64(s.ResourceID)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("EventType")
|
|
||||||
e.Int32(s.EventType)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("EventData")
|
|
||||||
s.EventData.Encode(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsonFieldsNameOfAuditEvent = [8]string{
|
|
||||||
0: "ID",
|
|
||||||
1: "Date",
|
|
||||||
2: "User",
|
|
||||||
3: "Username",
|
|
||||||
4: "ResourceType",
|
|
||||||
5: "ResourceID",
|
|
||||||
6: "EventType",
|
|
||||||
7: "EventData",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode decodes AuditEvent from json.
|
|
||||||
func (s *AuditEvent) Decode(d *jx.Decoder) error {
|
|
||||||
if s == nil {
|
|
||||||
return errors.New("invalid: unable to decode AuditEvent to nil")
|
|
||||||
}
|
|
||||||
var requiredBitSet [1]uint8
|
|
||||||
|
|
||||||
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
|
||||||
switch string(k) {
|
|
||||||
case "ID":
|
|
||||||
requiredBitSet[0] |= 1 << 0
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.ID = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"ID\"")
|
|
||||||
}
|
|
||||||
case "Date":
|
|
||||||
requiredBitSet[0] |= 1 << 1
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.Date = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Date\"")
|
|
||||||
}
|
|
||||||
case "User":
|
|
||||||
requiredBitSet[0] |= 1 << 2
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.User = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"User\"")
|
|
||||||
}
|
|
||||||
case "Username":
|
|
||||||
requiredBitSet[0] |= 1 << 3
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Str()
|
|
||||||
s.Username = string(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Username\"")
|
|
||||||
}
|
|
||||||
case "ResourceType":
|
|
||||||
requiredBitSet[0] |= 1 << 4
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int32()
|
|
||||||
s.ResourceType = int32(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"ResourceType\"")
|
|
||||||
}
|
|
||||||
case "ResourceID":
|
|
||||||
requiredBitSet[0] |= 1 << 5
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.ResourceID = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"ResourceID\"")
|
|
||||||
}
|
|
||||||
case "EventType":
|
|
||||||
requiredBitSet[0] |= 1 << 6
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int32()
|
|
||||||
s.EventType = int32(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"EventType\"")
|
|
||||||
}
|
|
||||||
case "EventData":
|
|
||||||
requiredBitSet[0] |= 1 << 7
|
|
||||||
if err := func() error {
|
|
||||||
if err := s.EventData.Decode(d); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"EventData\"")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return d.Skip()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return errors.Wrap(err, "decode AuditEvent")
|
|
||||||
}
|
|
||||||
// Validate required fields.
|
|
||||||
var failures []validate.FieldError
|
|
||||||
for i, mask := range [1]uint8{
|
|
||||||
0b11111111,
|
|
||||||
} {
|
|
||||||
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(jsonFieldsNameOfAuditEvent) {
|
|
||||||
name = jsonFieldsNameOfAuditEvent[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 *AuditEvent) MarshalJSON() ([]byte, error) {
|
|
||||||
e := jx.Encoder{}
|
|
||||||
s.Encode(&e)
|
|
||||||
return e.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements stdjson.Unmarshaler.
|
|
||||||
func (s *AuditEvent) UnmarshalJSON(data []byte) error {
|
|
||||||
d := jx.DecodeBytes(data)
|
|
||||||
return s.Decode(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
|
||||||
func (s AuditEventEventData) Encode(e *jx.Encoder) {
|
|
||||||
e.ObjStart()
|
|
||||||
s.encodeFields(e)
|
|
||||||
e.ObjEnd()
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeFields implements json.Marshaler.
|
|
||||||
func (s AuditEventEventData) encodeFields(e *jx.Encoder) {
|
|
||||||
for k, elem := range s {
|
|
||||||
e.FieldStart(k)
|
|
||||||
|
|
||||||
if len(elem) != 0 {
|
|
||||||
e.Raw(elem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode decodes AuditEventEventData from json.
|
|
||||||
func (s *AuditEventEventData) Decode(d *jx.Decoder) error {
|
|
||||||
if s == nil {
|
|
||||||
return errors.New("invalid: unable to decode AuditEventEventData to nil")
|
|
||||||
}
|
|
||||||
m := s.init()
|
|
||||||
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
|
||||||
var elem jx.Raw
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.RawAppend(nil)
|
|
||||||
elem = jx.Raw(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrapf(err, "decode field %q", k)
|
|
||||||
}
|
|
||||||
m[string(k)] = elem
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return errors.Wrap(err, "decode AuditEventEventData")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON implements stdjson.Marshaler.
|
|
||||||
func (s AuditEventEventData) MarshalJSON() ([]byte, error) {
|
|
||||||
e := jx.Encoder{}
|
|
||||||
s.Encode(&e)
|
|
||||||
return e.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements stdjson.Unmarshaler.
|
|
||||||
func (s *AuditEventEventData) 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()
|
||||||
@@ -619,8 +348,8 @@ func (s *Mapfix) encodeFields(e *jx.Encoder) {
|
|||||||
e.Int32(s.StatusID)
|
e.Int32(s.StatusID)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
e.FieldStart("Description")
|
e.FieldStart("StatusMessage")
|
||||||
e.Str(s.Description)
|
e.Str(s.StatusMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +366,7 @@ var jsonFieldsNameOfMapfix = [13]string{
|
|||||||
9: "Completed",
|
9: "Completed",
|
||||||
10: "TargetAssetID",
|
10: "TargetAssetID",
|
||||||
11: "StatusID",
|
11: "StatusID",
|
||||||
12: "Description",
|
12: "StatusMessage",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes Mapfix from json.
|
// Decode decodes Mapfix from json.
|
||||||
@@ -793,17 +522,17 @@ func (s *Mapfix) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"StatusID\"")
|
return errors.Wrap(err, "decode field \"StatusID\"")
|
||||||
}
|
}
|
||||||
case "Description":
|
case "StatusMessage":
|
||||||
requiredBitSet[1] |= 1 << 4
|
requiredBitSet[1] |= 1 << 4
|
||||||
if err := func() error {
|
if err := func() error {
|
||||||
v, err := d.Str()
|
v, err := d.Str()
|
||||||
s.Description = string(v)
|
s.StatusMessage = string(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"Description\"")
|
return errors.Wrap(err, "decode field \"StatusMessage\"")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
@@ -879,16 +608,11 @@ func (s *MapfixTriggerCreate) encodeFields(e *jx.Encoder) {
|
|||||||
e.FieldStart("TargetAssetID")
|
e.FieldStart("TargetAssetID")
|
||||||
e.Int64(s.TargetAssetID)
|
e.Int64(s.TargetAssetID)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
e.FieldStart("Description")
|
|
||||||
e.Str(s.Description)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfMapfixTriggerCreate = [3]string{
|
var jsonFieldsNameOfMapfixTriggerCreate = [2]string{
|
||||||
0: "AssetID",
|
0: "AssetID",
|
||||||
1: "TargetAssetID",
|
1: "TargetAssetID",
|
||||||
2: "Description",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes MapfixTriggerCreate from json.
|
// Decode decodes MapfixTriggerCreate from json.
|
||||||
@@ -924,18 +648,6 @@ func (s *MapfixTriggerCreate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"TargetAssetID\"")
|
return errors.Wrap(err, "decode field \"TargetAssetID\"")
|
||||||
}
|
}
|
||||||
case "Description":
|
|
||||||
requiredBitSet[0] |= 1 << 2
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Str()
|
|
||||||
s.Description = string(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Description\"")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
}
|
}
|
||||||
@@ -946,7 +658,7 @@ func (s *MapfixTriggerCreate) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00000111,
|
0b00000011,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -992,129 +704,6 @@ func (s *MapfixTriggerCreate) UnmarshalJSON(data []byte) error {
|
|||||||
return s.Decode(d)
|
return s.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
|
||||||
func (s *Mapfixes) Encode(e *jx.Encoder) {
|
|
||||||
e.ObjStart()
|
|
||||||
s.encodeFields(e)
|
|
||||||
e.ObjEnd()
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeFields encodes fields.
|
|
||||||
func (s *Mapfixes) encodeFields(e *jx.Encoder) {
|
|
||||||
{
|
|
||||||
e.FieldStart("Total")
|
|
||||||
e.Int64(s.Total)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("Mapfixes")
|
|
||||||
e.ArrStart()
|
|
||||||
for _, elem := range s.Mapfixes {
|
|
||||||
elem.Encode(e)
|
|
||||||
}
|
|
||||||
e.ArrEnd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsonFieldsNameOfMapfixes = [2]string{
|
|
||||||
0: "Total",
|
|
||||||
1: "Mapfixes",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode decodes Mapfixes from json.
|
|
||||||
func (s *Mapfixes) Decode(d *jx.Decoder) error {
|
|
||||||
if s == nil {
|
|
||||||
return errors.New("invalid: unable to decode Mapfixes to nil")
|
|
||||||
}
|
|
||||||
var requiredBitSet [1]uint8
|
|
||||||
|
|
||||||
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
|
||||||
switch string(k) {
|
|
||||||
case "Total":
|
|
||||||
requiredBitSet[0] |= 1 << 0
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.Total = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Total\"")
|
|
||||||
}
|
|
||||||
case "Mapfixes":
|
|
||||||
requiredBitSet[0] |= 1 << 1
|
|
||||||
if err := func() error {
|
|
||||||
s.Mapfixes = make([]Mapfix, 0)
|
|
||||||
if err := d.Arr(func(d *jx.Decoder) error {
|
|
||||||
var elem Mapfix
|
|
||||||
if err := elem.Decode(d); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Mapfixes = append(s.Mapfixes, elem)
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Mapfixes\"")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return d.Skip()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return errors.Wrap(err, "decode Mapfixes")
|
|
||||||
}
|
|
||||||
// Validate required fields.
|
|
||||||
var failures []validate.FieldError
|
|
||||||
for i, mask := range [1]uint8{
|
|
||||||
0b00000011,
|
|
||||||
} {
|
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
|
||||||
//
|
|
||||||
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
|
|
||||||
// Bits of fields which would be set are actually bits of missed fields.
|
|
||||||
missed := bits.OnesCount8(result)
|
|
||||||
for bitN := 0; bitN < missed; bitN++ {
|
|
||||||
bitIdx := bits.TrailingZeros8(result)
|
|
||||||
fieldIdx := i*8 + bitIdx
|
|
||||||
var name string
|
|
||||||
if fieldIdx < len(jsonFieldsNameOfMapfixes) {
|
|
||||||
name = jsonFieldsNameOfMapfixes[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 *Mapfixes) MarshalJSON() ([]byte, error) {
|
|
||||||
e := jx.Encoder{}
|
|
||||||
s.Encode(&e)
|
|
||||||
return e.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements stdjson.Unmarshaler.
|
|
||||||
func (s *Mapfixes) UnmarshalJSON(data []byte) error {
|
|
||||||
d := jx.DecodeBytes(data)
|
|
||||||
return s.Decode(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
// Encode implements json.Marshaler.
|
||||||
func (s *Operation) Encode(e *jx.Encoder) {
|
func (s *Operation) Encode(e *jx.Encoder) {
|
||||||
e.ObjStart()
|
e.ObjStart()
|
||||||
@@ -2885,9 +2474,13 @@ func (s *Submission) encodeFields(e *jx.Encoder) {
|
|||||||
e.FieldStart("StatusID")
|
e.FieldStart("StatusID")
|
||||||
e.Int32(s.StatusID)
|
e.Int32(s.StatusID)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
e.FieldStart("StatusMessage")
|
||||||
|
e.Str(s.StatusMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfSubmission = [14]string{
|
var jsonFieldsNameOfSubmission = [15]string{
|
||||||
0: "ID",
|
0: "ID",
|
||||||
1: "DisplayName",
|
1: "DisplayName",
|
||||||
2: "Creator",
|
2: "Creator",
|
||||||
@@ -2902,6 +2495,7 @@ var jsonFieldsNameOfSubmission = [14]string{
|
|||||||
11: "Completed",
|
11: "Completed",
|
||||||
12: "UploadedAssetID",
|
12: "UploadedAssetID",
|
||||||
13: "StatusID",
|
13: "StatusID",
|
||||||
|
14: "StatusMessage",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes Submission from json.
|
// Decode decodes Submission from json.
|
||||||
@@ -3075,6 +2669,18 @@ func (s *Submission) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"StatusID\"")
|
return errors.Wrap(err, "decode field \"StatusID\"")
|
||||||
}
|
}
|
||||||
|
case "StatusMessage":
|
||||||
|
requiredBitSet[1] |= 1 << 6
|
||||||
|
if err := func() error {
|
||||||
|
v, err := d.Str()
|
||||||
|
s.StatusMessage = string(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return errors.Wrap(err, "decode field \"StatusMessage\"")
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
}
|
}
|
||||||
@@ -3086,7 +2692,7 @@ func (s *Submission) Decode(d *jx.Decoder) error {
|
|||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [2]uint8{
|
for i, mask := range [2]uint8{
|
||||||
0b11111111,
|
0b11111111,
|
||||||
0b00101001,
|
0b01101001,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -3145,25 +2751,10 @@ func (s *SubmissionTriggerCreate) encodeFields(e *jx.Encoder) {
|
|||||||
e.FieldStart("AssetID")
|
e.FieldStart("AssetID")
|
||||||
e.Int64(s.AssetID)
|
e.Int64(s.AssetID)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
e.FieldStart("DisplayName")
|
|
||||||
e.Str(s.DisplayName)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("Creator")
|
|
||||||
e.Str(s.Creator)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("GameID")
|
|
||||||
e.Int32(s.GameID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonFieldsNameOfSubmissionTriggerCreate = [4]string{
|
var jsonFieldsNameOfSubmissionTriggerCreate = [1]string{
|
||||||
0: "AssetID",
|
0: "AssetID",
|
||||||
1: "DisplayName",
|
|
||||||
2: "Creator",
|
|
||||||
3: "GameID",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes SubmissionTriggerCreate from json.
|
// Decode decodes SubmissionTriggerCreate from json.
|
||||||
@@ -3187,42 +2778,6 @@ func (s *SubmissionTriggerCreate) Decode(d *jx.Decoder) error {
|
|||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return errors.Wrap(err, "decode field \"AssetID\"")
|
return errors.Wrap(err, "decode field \"AssetID\"")
|
||||||
}
|
}
|
||||||
case "DisplayName":
|
|
||||||
requiredBitSet[0] |= 1 << 1
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Str()
|
|
||||||
s.DisplayName = string(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"DisplayName\"")
|
|
||||||
}
|
|
||||||
case "Creator":
|
|
||||||
requiredBitSet[0] |= 1 << 2
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Str()
|
|
||||||
s.Creator = string(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Creator\"")
|
|
||||||
}
|
|
||||||
case "GameID":
|
|
||||||
requiredBitSet[0] |= 1 << 3
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int32()
|
|
||||||
s.GameID = int32(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"GameID\"")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return d.Skip()
|
return d.Skip()
|
||||||
}
|
}
|
||||||
@@ -3233,7 +2788,7 @@ func (s *SubmissionTriggerCreate) Decode(d *jx.Decoder) error {
|
|||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
var failures []validate.FieldError
|
var failures []validate.FieldError
|
||||||
for i, mask := range [1]uint8{
|
for i, mask := range [1]uint8{
|
||||||
0b00001111,
|
0b00000001,
|
||||||
} {
|
} {
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
// Mask only required fields and check equality to mask using XOR.
|
||||||
@@ -3279,129 +2834,6 @@ func (s *SubmissionTriggerCreate) UnmarshalJSON(data []byte) error {
|
|||||||
return s.Decode(d)
|
return s.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
|
||||||
func (s *Submissions) Encode(e *jx.Encoder) {
|
|
||||||
e.ObjStart()
|
|
||||||
s.encodeFields(e)
|
|
||||||
e.ObjEnd()
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeFields encodes fields.
|
|
||||||
func (s *Submissions) encodeFields(e *jx.Encoder) {
|
|
||||||
{
|
|
||||||
e.FieldStart("Total")
|
|
||||||
e.Int64(s.Total)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
e.FieldStart("Submissions")
|
|
||||||
e.ArrStart()
|
|
||||||
for _, elem := range s.Submissions {
|
|
||||||
elem.Encode(e)
|
|
||||||
}
|
|
||||||
e.ArrEnd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsonFieldsNameOfSubmissions = [2]string{
|
|
||||||
0: "Total",
|
|
||||||
1: "Submissions",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode decodes Submissions from json.
|
|
||||||
func (s *Submissions) Decode(d *jx.Decoder) error {
|
|
||||||
if s == nil {
|
|
||||||
return errors.New("invalid: unable to decode Submissions to nil")
|
|
||||||
}
|
|
||||||
var requiredBitSet [1]uint8
|
|
||||||
|
|
||||||
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
|
|
||||||
switch string(k) {
|
|
||||||
case "Total":
|
|
||||||
requiredBitSet[0] |= 1 << 0
|
|
||||||
if err := func() error {
|
|
||||||
v, err := d.Int64()
|
|
||||||
s.Total = int64(v)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Total\"")
|
|
||||||
}
|
|
||||||
case "Submissions":
|
|
||||||
requiredBitSet[0] |= 1 << 1
|
|
||||||
if err := func() error {
|
|
||||||
s.Submissions = make([]Submission, 0)
|
|
||||||
if err := d.Arr(func(d *jx.Decoder) error {
|
|
||||||
var elem Submission
|
|
||||||
if err := elem.Decode(d); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Submissions = append(s.Submissions, elem)
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}(); err != nil {
|
|
||||||
return errors.Wrap(err, "decode field \"Submissions\"")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return d.Skip()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return errors.Wrap(err, "decode Submissions")
|
|
||||||
}
|
|
||||||
// Validate required fields.
|
|
||||||
var failures []validate.FieldError
|
|
||||||
for i, mask := range [1]uint8{
|
|
||||||
0b00000011,
|
|
||||||
} {
|
|
||||||
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
|
|
||||||
// Mask only required fields and check equality to mask using XOR.
|
|
||||||
//
|
|
||||||
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
|
|
||||||
// Bits of fields which would be set are actually bits of missed fields.
|
|
||||||
missed := bits.OnesCount8(result)
|
|
||||||
for bitN := 0; bitN < missed; bitN++ {
|
|
||||||
bitIdx := bits.TrailingZeros8(result)
|
|
||||||
fieldIdx := i*8 + bitIdx
|
|
||||||
var name string
|
|
||||||
if fieldIdx < len(jsonFieldsNameOfSubmissions) {
|
|
||||||
name = jsonFieldsNameOfSubmissions[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 *Submissions) MarshalJSON() ([]byte, error) {
|
|
||||||
e := jx.Encoder{}
|
|
||||||
s.Encode(&e)
|
|
||||||
return e.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements stdjson.Unmarshaler.
|
|
||||||
func (s *Submissions) UnmarshalJSON(data []byte) error {
|
|
||||||
d := jx.DecodeBytes(data)
|
|
||||||
return s.Decode(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode implements json.Marshaler.
|
// Encode implements json.Marshaler.
|
||||||
func (s *User) Encode(e *jx.Encoder) {
|
func (s *User) Encode(e *jx.Encoder) {
|
||||||
e.ObjStart()
|
e.ObjStart()
|
||||||
|
|||||||
@@ -6,60 +6,49 @@ package api
|
|||||||
type OperationName = string
|
type OperationName = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
|
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
|
||||||
ActionMapfixRejectOperation OperationName = "ActionMapfixReject"
|
ActionMapfixRejectOperation OperationName = "ActionMapfixReject"
|
||||||
ActionMapfixRequestChangesOperation OperationName = "ActionMapfixRequestChanges"
|
ActionMapfixRequestChangesOperation OperationName = "ActionMapfixRequestChanges"
|
||||||
ActionMapfixResetSubmittingOperation OperationName = "ActionMapfixResetSubmitting"
|
ActionMapfixRetryValidateOperation OperationName = "ActionMapfixRetryValidate"
|
||||||
ActionMapfixRetryValidateOperation OperationName = "ActionMapfixRetryValidate"
|
ActionMapfixRevokeOperation OperationName = "ActionMapfixRevoke"
|
||||||
ActionMapfixRevokeOperation OperationName = "ActionMapfixRevoke"
|
ActionMapfixSubmitOperation OperationName = "ActionMapfixSubmit"
|
||||||
ActionMapfixTriggerSubmitOperation OperationName = "ActionMapfixTriggerSubmit"
|
ActionMapfixTriggerUploadOperation OperationName = "ActionMapfixTriggerUpload"
|
||||||
ActionMapfixTriggerSubmitUncheckedOperation OperationName = "ActionMapfixTriggerSubmitUnchecked"
|
ActionMapfixTriggerValidateOperation OperationName = "ActionMapfixTriggerValidate"
|
||||||
ActionMapfixTriggerUploadOperation OperationName = "ActionMapfixTriggerUpload"
|
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
|
||||||
ActionMapfixTriggerValidateOperation OperationName = "ActionMapfixTriggerValidate"
|
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
||||||
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
|
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
||||||
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
||||||
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
|
ActionSubmissionRetryValidateOperation OperationName = "ActionSubmissionRetryValidate"
|
||||||
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
|
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
||||||
ActionSubmissionResetSubmittingOperation OperationName = "ActionSubmissionResetSubmitting"
|
ActionSubmissionSubmitOperation OperationName = "ActionSubmissionSubmit"
|
||||||
ActionSubmissionRetryValidateOperation OperationName = "ActionSubmissionRetryValidate"
|
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
||||||
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
|
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
||||||
ActionSubmissionTriggerSubmitOperation OperationName = "ActionSubmissionTriggerSubmit"
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
ActionSubmissionTriggerSubmitUncheckedOperation OperationName = "ActionSubmissionTriggerSubmitUnchecked"
|
CreateMapfixOperation OperationName = "CreateMapfix"
|
||||||
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
CreateSubmissionOperation OperationName = "CreateSubmission"
|
||||||
CreateMapfixOperation OperationName = "CreateMapfix"
|
DeleteScriptOperation OperationName = "DeleteScript"
|
||||||
CreateMapfixAuditCommentOperation OperationName = "CreateMapfixAuditComment"
|
DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy"
|
||||||
CreateScriptOperation OperationName = "CreateScript"
|
GetMapOperation OperationName = "GetMap"
|
||||||
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
GetMapfixOperation OperationName = "GetMapfix"
|
||||||
CreateSubmissionOperation OperationName = "CreateSubmission"
|
GetOperationOperation OperationName = "GetOperation"
|
||||||
CreateSubmissionAdminOperation OperationName = "CreateSubmissionAdmin"
|
GetScriptOperation OperationName = "GetScript"
|
||||||
CreateSubmissionAuditCommentOperation OperationName = "CreateSubmissionAuditComment"
|
GetScriptPolicyOperation OperationName = "GetScriptPolicy"
|
||||||
DeleteScriptOperation OperationName = "DeleteScript"
|
GetSubmissionOperation OperationName = "GetSubmission"
|
||||||
DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy"
|
ListMapfixesOperation OperationName = "ListMapfixes"
|
||||||
DownloadMapAssetOperation OperationName = "DownloadMapAsset"
|
ListMapsOperation OperationName = "ListMaps"
|
||||||
GetMapOperation OperationName = "GetMap"
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
GetMapfixOperation OperationName = "GetMapfix"
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
GetOperationOperation OperationName = "GetOperation"
|
ListSubmissionsOperation OperationName = "ListSubmissions"
|
||||||
GetScriptOperation OperationName = "GetScript"
|
ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions"
|
||||||
GetScriptPolicyOperation OperationName = "GetScriptPolicy"
|
SessionRolesOperation OperationName = "SessionRoles"
|
||||||
GetSubmissionOperation OperationName = "GetSubmission"
|
SessionUserOperation OperationName = "SessionUser"
|
||||||
ListMapfixAuditEventsOperation OperationName = "ListMapfixAuditEvents"
|
SessionValidateOperation OperationName = "SessionValidate"
|
||||||
ListMapfixesOperation OperationName = "ListMapfixes"
|
SetMapfixCompletedOperation OperationName = "SetMapfixCompleted"
|
||||||
ListMapsOperation OperationName = "ListMaps"
|
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
||||||
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
UpdateMapfixModelOperation OperationName = "UpdateMapfixModel"
|
||||||
ListScriptsOperation OperationName = "ListScripts"
|
UpdateScriptOperation OperationName = "UpdateScript"
|
||||||
ListSubmissionAuditEventsOperation OperationName = "ListSubmissionAuditEvents"
|
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
||||||
ListSubmissionsOperation OperationName = "ListSubmissions"
|
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
|
||||||
MigrateMapsOperation OperationName = "MigrateMaps"
|
|
||||||
ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions"
|
|
||||||
SessionRolesOperation OperationName = "SessionRoles"
|
|
||||||
SessionUserOperation OperationName = "SessionUser"
|
|
||||||
SessionValidateOperation OperationName = "SessionValidate"
|
|
||||||
SetMapfixCompletedOperation OperationName = "SetMapfixCompleted"
|
|
||||||
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
|
|
||||||
UpdateMapfixModelOperation OperationName = "UpdateMapfixModel"
|
|
||||||
UpdateScriptOperation OperationName = "UpdateScript"
|
|
||||||
UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy"
|
|
||||||
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
|
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,13 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-faster/errors"
|
"github.com/go-faster/errors"
|
||||||
"github.com/go-faster/jx"
|
"github.com/go-faster/jx"
|
||||||
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"github.com/ogen-go/ogen/ogenerrors"
|
"github.com/ogen-go/ogen/ogenerrors"
|
||||||
"github.com/ogen-go/ogen/validate"
|
"github.com/ogen-go/ogen/validate"
|
||||||
@@ -26,13 +26,13 @@ func (s *Server) decodeCreateMapfixRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -72,54 +72,12 @@ func (s *Server) decodeCreateMapfixRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
return req, close, 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
|
return &request, close, nil
|
||||||
default:
|
default:
|
||||||
return req, close, validate.InvalidContentType(ct)
|
return req, close, validate.InvalidContentType(ct)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) decodeCreateMapfixAuditCommentRequest(r *http.Request) (
|
|
||||||
req CreateMapfixAuditCommentReq,
|
|
||||||
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 == "text/plain":
|
|
||||||
reader := r.Body
|
|
||||||
request := CreateMapfixAuditCommentReq{Data: reader}
|
|
||||||
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,
|
||||||
@@ -131,13 +89,13 @@ func (s *Server) decodeCreateScriptRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -202,13 +160,13 @@ func (s *Server) decodeCreateScriptPolicyRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -248,14 +206,6 @@ func (s *Server) decodeCreateScriptPolicyRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
return req, close, 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
|
return &request, close, nil
|
||||||
default:
|
default:
|
||||||
return req, close, validate.InvalidContentType(ct)
|
return req, close, validate.InvalidContentType(ct)
|
||||||
@@ -273,13 +223,13 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -319,125 +269,12 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
return req, close, 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
|
return &request, close, nil
|
||||||
default:
|
default:
|
||||||
return req, close, validate.InvalidContentType(ct)
|
return req, close, validate.InvalidContentType(ct)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) decodeCreateSubmissionAdminRequest(r *http.Request) (
|
|
||||||
req *SubmissionTriggerCreate,
|
|
||||||
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 SubmissionTriggerCreate
|
|
||||||
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) decodeCreateSubmissionAuditCommentRequest(r *http.Request) (
|
|
||||||
req CreateSubmissionAuditCommentReq,
|
|
||||||
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 == "text/plain":
|
|
||||||
reader := r.Body
|
|
||||||
request := CreateSubmissionAuditCommentReq{Data: reader}
|
|
||||||
return request, close, nil
|
|
||||||
default:
|
|
||||||
return req, close, validate.InvalidContentType(ct)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) (
|
func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) (
|
||||||
req []ReleaseInfo,
|
req []ReleaseInfo,
|
||||||
close func() error,
|
close func() error,
|
||||||
@@ -449,13 +286,13 @@ func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -515,23 +352,6 @@ func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) (
|
|||||||
}).ValidateLength(len(request)); err != nil {
|
}).ValidateLength(len(request)); err != nil {
|
||||||
return errors.Wrap(err, "array")
|
return errors.Wrap(err, "array")
|
||||||
}
|
}
|
||||||
var failures []validate.FieldError
|
|
||||||
for i, elem := range request {
|
|
||||||
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
|
return nil
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
return req, close, errors.Wrap(err, "validate")
|
return req, close, errors.Wrap(err, "validate")
|
||||||
@@ -553,13 +373,13 @@ func (s *Server) decodeUpdateScriptRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -624,13 +444,13 @@ func (s *Server) decodeUpdateScriptPolicyRequest(r *http.Request) (
|
|||||||
// Close in reverse order, to match defer behavior.
|
// Close in reverse order, to match defer behavior.
|
||||||
for i := len(closers) - 1; i >= 0; i-- {
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
c := closers[i]
|
c := closers[i]
|
||||||
merr = errors.Join(merr, c())
|
merr = multierr.Append(merr, c())
|
||||||
}
|
}
|
||||||
return merr
|
return merr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
rerr = errors.Join(rerr, close())
|
rerr = multierr.Append(rerr, close())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
@@ -670,14 +490,6 @@ func (s *Server) decodeUpdateScriptPolicyRequest(r *http.Request) (
|
|||||||
}
|
}
|
||||||
return req, close, 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
|
return &request, close, nil
|
||||||
default:
|
default:
|
||||||
return req, close, validate.InvalidContentType(ct)
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
|||||||
@@ -25,16 +25,6 @@ func encodeCreateMapfixRequest(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeCreateMapfixAuditCommentRequest(
|
|
||||||
req CreateMapfixAuditCommentReq,
|
|
||||||
r *http.Request,
|
|
||||||
) error {
|
|
||||||
const contentType = "text/plain"
|
|
||||||
body := req
|
|
||||||
ht.SetBody(r, body, contentType)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeCreateScriptRequest(
|
func encodeCreateScriptRequest(
|
||||||
req *ScriptCreate,
|
req *ScriptCreate,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
@@ -77,30 +67,6 @@ func encodeCreateSubmissionRequest(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeCreateSubmissionAdminRequest(
|
|
||||||
req *SubmissionTriggerCreate,
|
|
||||||
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 encodeCreateSubmissionAuditCommentRequest(
|
|
||||||
req CreateSubmissionAuditCommentReq,
|
|
||||||
r *http.Request,
|
|
||||||
) error {
|
|
||||||
const contentType = "text/plain"
|
|
||||||
body := req
|
|
||||||
ht.SetBody(r, body, contentType)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeReleaseSubmissionsRequest(
|
func encodeReleaseSubmissionsRequest(
|
||||||
req []ReleaseInfo,
|
req []ReleaseInfo,
|
||||||
r *http.Request,
|
r *http.Request,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-faster/errors"
|
"github.com/go-faster/errors"
|
||||||
@@ -35,13 +34,6 @@ func encodeActionMapfixRequestChangesResponse(response *ActionMapfixRequestChang
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionMapfixResetSubmittingResponse(response *ActionMapfixResetSubmittingNoContent, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeActionMapfixRetryValidateResponse(response *ActionMapfixRetryValidateNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionMapfixRetryValidateResponse(response *ActionMapfixRetryValidateNoContent, 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))
|
||||||
@@ -56,14 +48,7 @@ func encodeActionMapfixRevokeResponse(response *ActionMapfixRevokeNoContent, w h
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionMapfixTriggerSubmitResponse(response *ActionMapfixTriggerSubmitNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionMapfixSubmitResponse(response *ActionMapfixSubmitNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeActionMapfixTriggerSubmitUncheckedResponse(response *ActionMapfixTriggerSubmitUncheckedNoContent, 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))
|
||||||
|
|
||||||
@@ -112,13 +97,6 @@ func encodeActionSubmissionRequestChangesResponse(response *ActionSubmissionRequ
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionResetSubmittingResponse(response *ActionSubmissionResetSubmittingNoContent, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeActionSubmissionRetryValidateResponse(response *ActionSubmissionRetryValidateNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionSubmissionRetryValidateResponse(response *ActionSubmissionRetryValidateNoContent, 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))
|
||||||
@@ -133,14 +111,7 @@ func encodeActionSubmissionRevokeResponse(response *ActionSubmissionRevokeNoCont
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeActionSubmissionTriggerSubmitResponse(response *ActionSubmissionTriggerSubmitNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeActionSubmissionSubmitResponse(response *ActionSubmissionSubmitNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeActionSubmissionTriggerSubmitUncheckedResponse(response *ActionSubmissionTriggerSubmitUncheckedNoContent, 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))
|
||||||
|
|
||||||
@@ -182,13 +153,6 @@ func encodeCreateMapfixResponse(response *OperationID, w http.ResponseWriter, sp
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeCreateMapfixAuditCommentResponse(response *CreateMapfixAuditCommentNoContent, 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)
|
||||||
@@ -231,27 +195,6 @@ func encodeCreateSubmissionResponse(response *OperationID, w http.ResponseWriter
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeCreateSubmissionAdminResponse(response *OperationID, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
w.WriteHeader(201)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(201))
|
|
||||||
|
|
||||||
e := new(jx.Encoder)
|
|
||||||
response.Encode(e)
|
|
||||||
if _, err := e.WriteTo(w); err != nil {
|
|
||||||
return errors.Wrap(err, "write")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeCreateSubmissionAuditCommentResponse(response *CreateSubmissionAuditCommentNoContent, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.WriteHeader(204)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(204))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeDeleteScriptResponse(response *DeleteScriptNoContent, w http.ResponseWriter, span trace.Span) error {
|
func encodeDeleteScriptResponse(response *DeleteScriptNoContent, 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))
|
||||||
@@ -266,22 +209,6 @@ func encodeDeleteScriptPolicyResponse(response *DeleteScriptPolicyNoContent, w h
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeDownloadMapAssetResponse(response DownloadMapAssetOK, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.Header().Set("Content-Type", "application/octet-stream")
|
|
||||||
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 encodeGetMapResponse(response *Map, w http.ResponseWriter, span trace.Span) error {
|
func encodeGetMapResponse(response *Map, 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)
|
||||||
@@ -366,7 +293,7 @@ func encodeGetSubmissionResponse(response *Submission, w http.ResponseWriter, sp
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeListMapfixAuditEventsResponse(response []AuditEvent, w http.ResponseWriter, span trace.Span) error {
|
func encodeListMapfixesResponse(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)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(200))
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
@@ -384,20 +311,6 @@ func encodeListMapfixAuditEventsResponse(response []AuditEvent, w http.ResponseW
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeListMapfixesResponse(response *Mapfixes, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
w.WriteHeader(200)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(200))
|
|
||||||
|
|
||||||
e := new(jx.Encoder)
|
|
||||||
response.Encode(e)
|
|
||||||
if _, err := e.WriteTo(w); err != nil {
|
|
||||||
return errors.Wrap(err, "write")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeListMapsResponse(response []Map, w http.ResponseWriter, span trace.Span) error {
|
func encodeListMapsResponse(response []Map, 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)
|
||||||
@@ -452,7 +365,7 @@ func encodeListScriptsResponse(response []Script, w http.ResponseWriter, span tr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeListSubmissionAuditEventsResponse(response []AuditEvent, w http.ResponseWriter, span trace.Span) error {
|
func encodeListSubmissionsResponse(response []Submission, 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)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(200))
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
@@ -470,27 +383,6 @@ func encodeListSubmissionAuditEventsResponse(response []AuditEvent, w http.Respo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeListSubmissionsResponse(response *Submissions, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
w.WriteHeader(200)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(200))
|
|
||||||
|
|
||||||
e := new(jx.Encoder)
|
|
||||||
response.Encode(e)
|
|
||||||
if _, err := e.WriteTo(w); err != nil {
|
|
||||||
return errors.Wrap(err, "write")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeMigrateMapsResponse(response *MigrateMapsOK, w http.ResponseWriter, span trace.Span) error {
|
|
||||||
w.WriteHeader(200)
|
|
||||||
span.SetStatus(codes.Ok, http.StatusText(200))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeReleaseSubmissionsResponse(response *ReleaseSubmissionsCreated, w http.ResponseWriter, span trace.Span) error {
|
func encodeReleaseSubmissionsResponse(response *ReleaseSubmissionsCreated, w http.ResponseWriter, span trace.Span) error {
|
||||||
w.WriteHeader(201)
|
w.WriteHeader(201)
|
||||||
span.SetStatus(codes.Ok, http.StatusText(201))
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-faster/jx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *ErrorStatusCode) Error() string {
|
func (s *ErrorStatusCode) Error() string {
|
||||||
@@ -23,20 +20,14 @@ type ActionMapfixRejectNoContent struct{}
|
|||||||
// ActionMapfixRequestChangesNoContent is response for ActionMapfixRequestChanges operation.
|
// ActionMapfixRequestChangesNoContent is response for ActionMapfixRequestChanges operation.
|
||||||
type ActionMapfixRequestChangesNoContent struct{}
|
type ActionMapfixRequestChangesNoContent struct{}
|
||||||
|
|
||||||
// ActionMapfixResetSubmittingNoContent is response for ActionMapfixResetSubmitting operation.
|
|
||||||
type ActionMapfixResetSubmittingNoContent struct{}
|
|
||||||
|
|
||||||
// ActionMapfixRetryValidateNoContent is response for ActionMapfixRetryValidate operation.
|
// ActionMapfixRetryValidateNoContent is response for ActionMapfixRetryValidate operation.
|
||||||
type ActionMapfixRetryValidateNoContent struct{}
|
type ActionMapfixRetryValidateNoContent struct{}
|
||||||
|
|
||||||
// ActionMapfixRevokeNoContent is response for ActionMapfixRevoke operation.
|
// ActionMapfixRevokeNoContent is response for ActionMapfixRevoke operation.
|
||||||
type ActionMapfixRevokeNoContent struct{}
|
type ActionMapfixRevokeNoContent struct{}
|
||||||
|
|
||||||
// ActionMapfixTriggerSubmitNoContent is response for ActionMapfixTriggerSubmit operation.
|
// ActionMapfixSubmitNoContent is response for ActionMapfixSubmit operation.
|
||||||
type ActionMapfixTriggerSubmitNoContent struct{}
|
type ActionMapfixSubmitNoContent 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{}
|
||||||
@@ -56,20 +47,14 @@ type ActionSubmissionRejectNoContent struct{}
|
|||||||
// ActionSubmissionRequestChangesNoContent is response for ActionSubmissionRequestChanges operation.
|
// ActionSubmissionRequestChangesNoContent is response for ActionSubmissionRequestChanges operation.
|
||||||
type ActionSubmissionRequestChangesNoContent struct{}
|
type ActionSubmissionRequestChangesNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionResetSubmittingNoContent is response for ActionSubmissionResetSubmitting operation.
|
|
||||||
type ActionSubmissionResetSubmittingNoContent struct{}
|
|
||||||
|
|
||||||
// ActionSubmissionRetryValidateNoContent is response for ActionSubmissionRetryValidate operation.
|
// ActionSubmissionRetryValidateNoContent is response for ActionSubmissionRetryValidate operation.
|
||||||
type ActionSubmissionRetryValidateNoContent struct{}
|
type ActionSubmissionRetryValidateNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionRevokeNoContent is response for ActionSubmissionRevoke operation.
|
// ActionSubmissionRevokeNoContent is response for ActionSubmissionRevoke operation.
|
||||||
type ActionSubmissionRevokeNoContent struct{}
|
type ActionSubmissionRevokeNoContent struct{}
|
||||||
|
|
||||||
// ActionSubmissionTriggerSubmitNoContent is response for ActionSubmissionTriggerSubmit operation.
|
// ActionSubmissionSubmitNoContent is response for ActionSubmissionSubmit operation.
|
||||||
type ActionSubmissionTriggerSubmitNoContent struct{}
|
type ActionSubmissionSubmitNoContent 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{}
|
||||||
@@ -80,115 +65,8 @@ type ActionSubmissionTriggerValidateNoContent struct{}
|
|||||||
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
||||||
type ActionSubmissionValidatedNoContent struct{}
|
type ActionSubmissionValidatedNoContent struct{}
|
||||||
|
|
||||||
// Ref: #/components/schemas/AuditEvent
|
|
||||||
type AuditEvent struct {
|
|
||||||
ID int64 `json:"ID"`
|
|
||||||
Date int64 `json:"Date"`
|
|
||||||
User int64 `json:"User"`
|
|
||||||
Username string `json:"Username"`
|
|
||||||
// Is this a submission or is it a mapfix.
|
|
||||||
ResourceType int32 `json:"ResourceType"`
|
|
||||||
ResourceID int64 `json:"ResourceID"`
|
|
||||||
EventType int32 `json:"EventType"`
|
|
||||||
// Arbitrary event data.
|
|
||||||
EventData AuditEventEventData `json:"EventData"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
|
||||||
func (s *AuditEvent) GetID() int64 {
|
|
||||||
return s.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDate returns the value of Date.
|
|
||||||
func (s *AuditEvent) GetDate() int64 {
|
|
||||||
return s.Date
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUser returns the value of User.
|
|
||||||
func (s *AuditEvent) GetUser() int64 {
|
|
||||||
return s.User
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUsername returns the value of Username.
|
|
||||||
func (s *AuditEvent) GetUsername() string {
|
|
||||||
return s.Username
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetResourceType returns the value of ResourceType.
|
|
||||||
func (s *AuditEvent) GetResourceType() int32 {
|
|
||||||
return s.ResourceType
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetResourceID returns the value of ResourceID.
|
|
||||||
func (s *AuditEvent) GetResourceID() int64 {
|
|
||||||
return s.ResourceID
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEventType returns the value of EventType.
|
|
||||||
func (s *AuditEvent) GetEventType() int32 {
|
|
||||||
return s.EventType
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEventData returns the value of EventData.
|
|
||||||
func (s *AuditEvent) GetEventData() AuditEventEventData {
|
|
||||||
return s.EventData
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
|
||||||
func (s *AuditEvent) SetID(val int64) {
|
|
||||||
s.ID = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDate sets the value of Date.
|
|
||||||
func (s *AuditEvent) SetDate(val int64) {
|
|
||||||
s.Date = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUser sets the value of User.
|
|
||||||
func (s *AuditEvent) SetUser(val int64) {
|
|
||||||
s.User = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUsername sets the value of Username.
|
|
||||||
func (s *AuditEvent) SetUsername(val string) {
|
|
||||||
s.Username = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResourceType sets the value of ResourceType.
|
|
||||||
func (s *AuditEvent) SetResourceType(val int32) {
|
|
||||||
s.ResourceType = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetResourceID sets the value of ResourceID.
|
|
||||||
func (s *AuditEvent) SetResourceID(val int64) {
|
|
||||||
s.ResourceID = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEventType sets the value of EventType.
|
|
||||||
func (s *AuditEvent) SetEventType(val int32) {
|
|
||||||
s.EventType = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEventData sets the value of EventData.
|
|
||||||
func (s *AuditEvent) SetEventData(val AuditEventEventData) {
|
|
||||||
s.EventData = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arbitrary event data.
|
|
||||||
type AuditEventEventData map[string]jx.Raw
|
|
||||||
|
|
||||||
func (s *AuditEventEventData) init() AuditEventEventData {
|
|
||||||
m := *s
|
|
||||||
if m == nil {
|
|
||||||
m = map[string]jx.Raw{}
|
|
||||||
*s = m
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
type CookieAuth struct {
|
type CookieAuth struct {
|
||||||
APIKey string
|
APIKey string
|
||||||
Roles []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAPIKey returns the value of APIKey.
|
// GetAPIKey returns the value of APIKey.
|
||||||
@@ -196,75 +74,17 @@ func (s *CookieAuth) GetAPIKey() string {
|
|||||||
return s.APIKey
|
return s.APIKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRoles returns the value of Roles.
|
|
||||||
func (s *CookieAuth) GetRoles() []string {
|
|
||||||
return s.Roles
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAPIKey sets the value of APIKey.
|
// SetAPIKey sets the value of APIKey.
|
||||||
func (s *CookieAuth) SetAPIKey(val string) {
|
func (s *CookieAuth) SetAPIKey(val string) {
|
||||||
s.APIKey = val
|
s.APIKey = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRoles sets the value of Roles.
|
|
||||||
func (s *CookieAuth) SetRoles(val []string) {
|
|
||||||
s.Roles = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMapfixAuditCommentNoContent is response for CreateMapfixAuditComment operation.
|
|
||||||
type CreateMapfixAuditCommentNoContent struct{}
|
|
||||||
|
|
||||||
type CreateMapfixAuditCommentReq struct {
|
|
||||||
Data io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads data from the Data reader.
|
|
||||||
//
|
|
||||||
// Kept to satisfy the io.Reader interface.
|
|
||||||
func (s CreateMapfixAuditCommentReq) Read(p []byte) (n int, err error) {
|
|
||||||
if s.Data == nil {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
return s.Data.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSubmissionAuditCommentNoContent is response for CreateSubmissionAuditComment operation.
|
|
||||||
type CreateSubmissionAuditCommentNoContent struct{}
|
|
||||||
|
|
||||||
type CreateSubmissionAuditCommentReq struct {
|
|
||||||
Data io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads data from the Data reader.
|
|
||||||
//
|
|
||||||
// Kept to satisfy the io.Reader interface.
|
|
||||||
func (s CreateSubmissionAuditCommentReq) Read(p []byte) (n int, err error) {
|
|
||||||
if s.Data == nil {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
return s.Data.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteScriptNoContent is response for DeleteScript operation.
|
// DeleteScriptNoContent is response for DeleteScript operation.
|
||||||
type DeleteScriptNoContent struct{}
|
type DeleteScriptNoContent struct{}
|
||||||
|
|
||||||
// DeleteScriptPolicyNoContent is response for DeleteScriptPolicy operation.
|
// DeleteScriptPolicyNoContent is response for DeleteScriptPolicy operation.
|
||||||
type DeleteScriptPolicyNoContent struct{}
|
type DeleteScriptPolicyNoContent struct{}
|
||||||
|
|
||||||
type DownloadMapAssetOK struct {
|
|
||||||
Data io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads data from the Data reader.
|
|
||||||
//
|
|
||||||
// Kept to satisfy the io.Reader interface.
|
|
||||||
func (s DownloadMapAssetOK) Read(p []byte) (n int, err error) {
|
|
||||||
if s.Data == nil {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
return s.Data.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Represents error object.
|
// Represents error object.
|
||||||
// Ref: #/components/schemas/Error
|
// Ref: #/components/schemas/Error
|
||||||
type Error struct {
|
type Error struct {
|
||||||
@@ -391,7 +211,7 @@ type Mapfix struct {
|
|||||||
Completed bool `json:"Completed"`
|
Completed bool `json:"Completed"`
|
||||||
TargetAssetID int64 `json:"TargetAssetID"`
|
TargetAssetID int64 `json:"TargetAssetID"`
|
||||||
StatusID int32 `json:"StatusID"`
|
StatusID int32 `json:"StatusID"`
|
||||||
Description string `json:"Description"`
|
StatusMessage string `json:"StatusMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -454,9 +274,9 @@ func (s *Mapfix) GetStatusID() int32 {
|
|||||||
return s.StatusID
|
return s.StatusID
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDescription returns the value of Description.
|
// GetStatusMessage returns the value of StatusMessage.
|
||||||
func (s *Mapfix) GetDescription() string {
|
func (s *Mapfix) GetStatusMessage() string {
|
||||||
return s.Description
|
return s.StatusMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
@@ -519,16 +339,15 @@ func (s *Mapfix) SetStatusID(val int32) {
|
|||||||
s.StatusID = val
|
s.StatusID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDescription sets the value of Description.
|
// SetStatusMessage sets the value of StatusMessage.
|
||||||
func (s *Mapfix) SetDescription(val string) {
|
func (s *Mapfix) SetStatusMessage(val string) {
|
||||||
s.Description = val
|
s.StatusMessage = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/MapfixTriggerCreate
|
// Ref: #/components/schemas/MapfixTriggerCreate
|
||||||
type MapfixTriggerCreate struct {
|
type MapfixTriggerCreate struct {
|
||||||
AssetID int64 `json:"AssetID"`
|
AssetID int64 `json:"AssetID"`
|
||||||
TargetAssetID int64 `json:"TargetAssetID"`
|
TargetAssetID int64 `json:"TargetAssetID"`
|
||||||
Description string `json:"Description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetID returns the value of AssetID.
|
// GetAssetID returns the value of AssetID.
|
||||||
@@ -541,11 +360,6 @@ func (s *MapfixTriggerCreate) GetTargetAssetID() int64 {
|
|||||||
return s.TargetAssetID
|
return s.TargetAssetID
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDescription returns the value of Description.
|
|
||||||
func (s *MapfixTriggerCreate) GetDescription() string {
|
|
||||||
return s.Description
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAssetID sets the value of AssetID.
|
// SetAssetID sets the value of AssetID.
|
||||||
func (s *MapfixTriggerCreate) SetAssetID(val int64) {
|
func (s *MapfixTriggerCreate) SetAssetID(val int64) {
|
||||||
s.AssetID = val
|
s.AssetID = val
|
||||||
@@ -556,40 +370,6 @@ func (s *MapfixTriggerCreate) SetTargetAssetID(val int64) {
|
|||||||
s.TargetAssetID = val
|
s.TargetAssetID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDescription sets the value of Description.
|
|
||||||
func (s *MapfixTriggerCreate) SetDescription(val string) {
|
|
||||||
s.Description = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ref: #/components/schemas/Mapfixes
|
|
||||||
type Mapfixes struct {
|
|
||||||
Total int64 `json:"Total"`
|
|
||||||
Mapfixes []Mapfix `json:"Mapfixes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTotal returns the value of Total.
|
|
||||||
func (s *Mapfixes) GetTotal() int64 {
|
|
||||||
return s.Total
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMapfixes returns the value of Mapfixes.
|
|
||||||
func (s *Mapfixes) GetMapfixes() []Mapfix {
|
|
||||||
return s.Mapfixes
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTotal sets the value of Total.
|
|
||||||
func (s *Mapfixes) SetTotal(val int64) {
|
|
||||||
s.Total = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMapfixes sets the value of Mapfixes.
|
|
||||||
func (s *Mapfixes) SetMapfixes(val []Mapfix) {
|
|
||||||
s.Mapfixes = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// MigrateMapsOK is response for MigrateMaps operation.
|
|
||||||
type MigrateMapsOK struct{}
|
|
||||||
|
|
||||||
// Ref: #/components/schemas/Operation
|
// Ref: #/components/schemas/Operation
|
||||||
type Operation struct {
|
type Operation struct {
|
||||||
OperationID int32 `json:"OperationID"`
|
OperationID int32 `json:"OperationID"`
|
||||||
@@ -1219,6 +999,7 @@ type Submission struct {
|
|||||||
Completed bool `json:"Completed"`
|
Completed bool `json:"Completed"`
|
||||||
UploadedAssetID OptInt64 `json:"UploadedAssetID"`
|
UploadedAssetID OptInt64 `json:"UploadedAssetID"`
|
||||||
StatusID int32 `json:"StatusID"`
|
StatusID int32 `json:"StatusID"`
|
||||||
|
StatusMessage string `json:"StatusMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID returns the value of ID.
|
// GetID returns the value of ID.
|
||||||
@@ -1291,6 +1072,11 @@ func (s *Submission) GetStatusID() int32 {
|
|||||||
return s.StatusID
|
return s.StatusID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetStatusMessage returns the value of StatusMessage.
|
||||||
|
func (s *Submission) GetStatusMessage() string {
|
||||||
|
return s.StatusMessage
|
||||||
|
}
|
||||||
|
|
||||||
// SetID sets the value of ID.
|
// SetID sets the value of ID.
|
||||||
func (s *Submission) SetID(val int64) {
|
func (s *Submission) SetID(val int64) {
|
||||||
s.ID = val
|
s.ID = val
|
||||||
@@ -1361,12 +1147,14 @@ func (s *Submission) SetStatusID(val int32) {
|
|||||||
s.StatusID = val
|
s.StatusID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStatusMessage sets the value of StatusMessage.
|
||||||
|
func (s *Submission) SetStatusMessage(val string) {
|
||||||
|
s.StatusMessage = val
|
||||||
|
}
|
||||||
|
|
||||||
// Ref: #/components/schemas/SubmissionTriggerCreate
|
// Ref: #/components/schemas/SubmissionTriggerCreate
|
||||||
type SubmissionTriggerCreate struct {
|
type SubmissionTriggerCreate struct {
|
||||||
AssetID int64 `json:"AssetID"`
|
AssetID int64 `json:"AssetID"`
|
||||||
DisplayName string `json:"DisplayName"`
|
|
||||||
Creator string `json:"Creator"`
|
|
||||||
GameID int32 `json:"GameID"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetID returns the value of AssetID.
|
// GetAssetID returns the value of AssetID.
|
||||||
@@ -1374,67 +1162,11 @@ func (s *SubmissionTriggerCreate) GetAssetID() int64 {
|
|||||||
return s.AssetID
|
return s.AssetID
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisplayName returns the value of DisplayName.
|
|
||||||
func (s *SubmissionTriggerCreate) GetDisplayName() string {
|
|
||||||
return s.DisplayName
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCreator returns the value of Creator.
|
|
||||||
func (s *SubmissionTriggerCreate) GetCreator() string {
|
|
||||||
return s.Creator
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGameID returns the value of GameID.
|
|
||||||
func (s *SubmissionTriggerCreate) GetGameID() int32 {
|
|
||||||
return s.GameID
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAssetID sets the value of AssetID.
|
// SetAssetID sets the value of AssetID.
|
||||||
func (s *SubmissionTriggerCreate) SetAssetID(val int64) {
|
func (s *SubmissionTriggerCreate) SetAssetID(val int64) {
|
||||||
s.AssetID = val
|
s.AssetID = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDisplayName sets the value of DisplayName.
|
|
||||||
func (s *SubmissionTriggerCreate) SetDisplayName(val string) {
|
|
||||||
s.DisplayName = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCreator sets the value of Creator.
|
|
||||||
func (s *SubmissionTriggerCreate) SetCreator(val string) {
|
|
||||||
s.Creator = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGameID sets the value of GameID.
|
|
||||||
func (s *SubmissionTriggerCreate) SetGameID(val int32) {
|
|
||||||
s.GameID = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ref: #/components/schemas/Submissions
|
|
||||||
type Submissions struct {
|
|
||||||
Total int64 `json:"Total"`
|
|
||||||
Submissions []Submission `json:"Submissions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTotal returns the value of Total.
|
|
||||||
func (s *Submissions) GetTotal() int64 {
|
|
||||||
return s.Total
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSubmissions returns the value of Submissions.
|
|
||||||
func (s *Submissions) GetSubmissions() []Submission {
|
|
||||||
return s.Submissions
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTotal sets the value of Total.
|
|
||||||
func (s *Submissions) SetTotal(val int64) {
|
|
||||||
s.Total = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSubmissions sets the value of Submissions.
|
|
||||||
func (s *Submissions) SetSubmissions(val []Submission) {
|
|
||||||
s.Submissions = val
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMapfixModelNoContent is response for UpdateMapfixModel operation.
|
// UpdateMapfixModelNoContent is response for UpdateMapfixModel operation.
|
||||||
type UpdateMapfixModelNoContent struct{}
|
type UpdateMapfixModelNoContent struct{}
|
||||||
|
|
||||||
|
|||||||
@@ -33,53 +33,6 @@ func findAuthorization(h http.Header, prefix string) (string, bool) {
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
var operationRolesCookieAuth = map[string][]string{
|
|
||||||
ActionMapfixAcceptedOperation: []string{},
|
|
||||||
ActionMapfixRejectOperation: []string{},
|
|
||||||
ActionMapfixRequestChangesOperation: []string{},
|
|
||||||
ActionMapfixResetSubmittingOperation: []string{},
|
|
||||||
ActionMapfixRetryValidateOperation: []string{},
|
|
||||||
ActionMapfixRevokeOperation: []string{},
|
|
||||||
ActionMapfixTriggerSubmitOperation: []string{},
|
|
||||||
ActionMapfixTriggerSubmitUncheckedOperation: []string{},
|
|
||||||
ActionMapfixTriggerUploadOperation: []string{},
|
|
||||||
ActionMapfixTriggerValidateOperation: []string{},
|
|
||||||
ActionMapfixValidatedOperation: []string{},
|
|
||||||
ActionSubmissionAcceptedOperation: []string{},
|
|
||||||
ActionSubmissionRejectOperation: []string{},
|
|
||||||
ActionSubmissionRequestChangesOperation: []string{},
|
|
||||||
ActionSubmissionResetSubmittingOperation: []string{},
|
|
||||||
ActionSubmissionRetryValidateOperation: []string{},
|
|
||||||
ActionSubmissionRevokeOperation: []string{},
|
|
||||||
ActionSubmissionTriggerSubmitOperation: []string{},
|
|
||||||
ActionSubmissionTriggerSubmitUncheckedOperation: []string{},
|
|
||||||
ActionSubmissionTriggerUploadOperation: []string{},
|
|
||||||
ActionSubmissionTriggerValidateOperation: []string{},
|
|
||||||
ActionSubmissionValidatedOperation: []string{},
|
|
||||||
CreateMapfixOperation: []string{},
|
|
||||||
CreateMapfixAuditCommentOperation: []string{},
|
|
||||||
CreateScriptOperation: []string{},
|
|
||||||
CreateScriptPolicyOperation: []string{},
|
|
||||||
CreateSubmissionOperation: []string{},
|
|
||||||
CreateSubmissionAdminOperation: []string{},
|
|
||||||
CreateSubmissionAuditCommentOperation: []string{},
|
|
||||||
DeleteScriptOperation: []string{},
|
|
||||||
DeleteScriptPolicyOperation: []string{},
|
|
||||||
DownloadMapAssetOperation: []string{},
|
|
||||||
GetOperationOperation: []string{},
|
|
||||||
MigrateMapsOperation: []string{},
|
|
||||||
ReleaseSubmissionsOperation: []string{},
|
|
||||||
SessionRolesOperation: []string{},
|
|
||||||
SessionUserOperation: []string{},
|
|
||||||
SessionValidateOperation: []string{},
|
|
||||||
SetMapfixCompletedOperation: []string{},
|
|
||||||
SetSubmissionCompletedOperation: []string{},
|
|
||||||
UpdateMapfixModelOperation: []string{},
|
|
||||||
UpdateScriptOperation: []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) {
|
||||||
var t CookieAuth
|
var t CookieAuth
|
||||||
const parameterName = "session_id"
|
const parameterName = "session_id"
|
||||||
@@ -93,7 +46,6 @@ func (s *Server) securityCookieAuth(ctx context.Context, operationName Operation
|
|||||||
return nil, false, errors.Wrap(err, "get cookie value")
|
return nil, false, errors.Wrap(err, "get cookie value")
|
||||||
}
|
}
|
||||||
t.APIKey = value
|
t.APIKey = value
|
||||||
t.Roles = operationRolesCookieAuth[operationName]
|
|
||||||
rctx, err := s.sec.HandleCookieAuth(ctx, operationName, t)
|
rctx, err := s.sec.HandleCookieAuth(ctx, operationName, t)
|
||||||
if errors.Is(err, ogenerrors.ErrSkipServerSecurity) {
|
if errors.Is(err, ogenerrors.ErrSkipServerSecurity) {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/request-changes
|
// POST /mapfixes/{MapfixID}/status/request-changes
|
||||||
ActionMapfixRequestChanges(ctx context.Context, params ActionMapfixRequestChangesParams) error
|
ActionMapfixRequestChanges(ctx context.Context, params ActionMapfixRequestChangesParams) error
|
||||||
// ActionMapfixResetSubmitting implements actionMapfixResetSubmitting operation.
|
|
||||||
//
|
|
||||||
// Role Submitter manually resets submitting softlock and changes status from Submitting ->
|
|
||||||
// UnderConstruction.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/reset-submitting
|
|
||||||
ActionMapfixResetSubmitting(ctx context.Context, params ActionMapfixResetSubmittingParams) error
|
|
||||||
// ActionMapfixRetryValidate implements actionMapfixRetryValidate operation.
|
// ActionMapfixRetryValidate implements actionMapfixRetryValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
@@ -45,18 +38,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/revoke
|
// POST /mapfixes/{MapfixID}/status/revoke
|
||||||
ActionMapfixRevoke(ctx context.Context, params ActionMapfixRevokeParams) error
|
ActionMapfixRevoke(ctx context.Context, params ActionMapfixRevokeParams) error
|
||||||
// ActionMapfixTriggerSubmit implements actionMapfixTriggerSubmit operation.
|
// ActionMapfixSubmit implements actionMapfixSubmit operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitting.
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
// POST /mapfixes/{MapfixID}/status/submit
|
||||||
ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error
|
ActionMapfixSubmit(ctx context.Context, params ActionMapfixSubmitParams) 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.
|
||||||
@@ -93,13 +80,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/request-changes
|
// POST /submissions/{SubmissionID}/status/request-changes
|
||||||
ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error
|
ActionSubmissionRequestChanges(ctx context.Context, params ActionSubmissionRequestChangesParams) error
|
||||||
// ActionSubmissionResetSubmitting implements actionSubmissionResetSubmitting operation.
|
|
||||||
//
|
|
||||||
// Role Submitter manually resets submitting softlock and changes status from Submitting ->
|
|
||||||
// UnderConstruction.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/reset-submitting
|
|
||||||
ActionSubmissionResetSubmitting(ctx context.Context, params ActionSubmissionResetSubmittingParams) error
|
|
||||||
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
@@ -112,18 +92,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/revoke
|
// POST /submissions/{SubmissionID}/status/revoke
|
||||||
ActionSubmissionRevoke(ctx context.Context, params ActionSubmissionRevokeParams) error
|
ActionSubmissionRevoke(ctx context.Context, params ActionSubmissionRevokeParams) error
|
||||||
// ActionSubmissionTriggerSubmit implements actionSubmissionTriggerSubmit operation.
|
// ActionSubmissionSubmit implements actionSubmissionSubmit operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitting.
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-submit
|
// POST /submissions/{SubmissionID}/status/submit
|
||||||
ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error
|
ActionSubmissionSubmit(ctx context.Context, params ActionSubmissionSubmitParams) 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.
|
||||||
@@ -148,12 +122,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /mapfixes
|
// POST /mapfixes
|
||||||
CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (*OperationID, error)
|
CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (*OperationID, error)
|
||||||
// CreateMapfixAuditComment implements createMapfixAuditComment operation.
|
|
||||||
//
|
|
||||||
// Post a comment to the audit log.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/comment
|
|
||||||
CreateMapfixAuditComment(ctx context.Context, req CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error
|
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -172,18 +140,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// POST /submissions
|
// POST /submissions
|
||||||
CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (*OperationID, error)
|
CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (*OperationID, error)
|
||||||
// CreateSubmissionAdmin implements createSubmissionAdmin operation.
|
|
||||||
//
|
|
||||||
// Trigger the validator to create a new submission.
|
|
||||||
//
|
|
||||||
// POST /submissions-admin
|
|
||||||
CreateSubmissionAdmin(ctx context.Context, req *SubmissionTriggerCreate) (*OperationID, error)
|
|
||||||
// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.
|
|
||||||
//
|
|
||||||
// Post a comment to the audit log.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/comment
|
|
||||||
CreateSubmissionAuditComment(ctx context.Context, req CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error
|
|
||||||
// DeleteScript implements deleteScript operation.
|
// DeleteScript implements deleteScript operation.
|
||||||
//
|
//
|
||||||
// Delete the specified script by ID.
|
// Delete the specified script by ID.
|
||||||
@@ -196,12 +152,6 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// DELETE /script-policy/{ScriptPolicyID}
|
// DELETE /script-policy/{ScriptPolicyID}
|
||||||
DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error
|
DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error
|
||||||
// DownloadMapAsset implements downloadMapAsset operation.
|
|
||||||
//
|
|
||||||
// Download the map asset.
|
|
||||||
//
|
|
||||||
// GET /maps/{MapID}/download
|
|
||||||
DownloadMapAsset(ctx context.Context, params DownloadMapAssetParams) (DownloadMapAssetOK, error)
|
|
||||||
// GetMap implements getMap operation.
|
// GetMap implements getMap operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
@@ -238,18 +188,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// GET /submissions/{SubmissionID}
|
// GET /submissions/{SubmissionID}
|
||||||
GetSubmission(ctx context.Context, params GetSubmissionParams) (*Submission, error)
|
GetSubmission(ctx context.Context, params GetSubmissionParams) (*Submission, error)
|
||||||
// ListMapfixAuditEvents implements listMapfixAuditEvents operation.
|
|
||||||
//
|
|
||||||
// Retrieve a list of audit events.
|
|
||||||
//
|
|
||||||
// GET /mapfixes/{MapfixID}/audit-events
|
|
||||||
ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) ([]AuditEvent, error)
|
|
||||||
// ListMapfixes implements listMapfixes operation.
|
// ListMapfixes implements listMapfixes operation.
|
||||||
//
|
//
|
||||||
// Get list of mapfixes.
|
// Get list of mapfixes.
|
||||||
//
|
//
|
||||||
// GET /mapfixes
|
// GET /mapfixes
|
||||||
ListMapfixes(ctx context.Context, params ListMapfixesParams) (*Mapfixes, error)
|
ListMapfixes(ctx context.Context, params ListMapfixesParams) ([]Mapfix, error)
|
||||||
// ListMaps implements listMaps operation.
|
// ListMaps implements listMaps operation.
|
||||||
//
|
//
|
||||||
// Get list of maps.
|
// Get list of maps.
|
||||||
@@ -268,24 +212,12 @@ type Handler interface {
|
|||||||
//
|
//
|
||||||
// GET /scripts
|
// GET /scripts
|
||||||
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
||||||
// ListSubmissionAuditEvents implements listSubmissionAuditEvents operation.
|
|
||||||
//
|
|
||||||
// Retrieve a list of audit events.
|
|
||||||
//
|
|
||||||
// GET /submissions/{SubmissionID}/audit-events
|
|
||||||
ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) ([]AuditEvent, error)
|
|
||||||
// ListSubmissions implements listSubmissions operation.
|
// ListSubmissions implements listSubmissions operation.
|
||||||
//
|
//
|
||||||
// Get list of submissions.
|
// Get list of submissions.
|
||||||
//
|
//
|
||||||
// GET /submissions
|
// GET /submissions
|
||||||
ListSubmissions(ctx context.Context, params ListSubmissionsParams) (*Submissions, error)
|
ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error)
|
||||||
// MigrateMaps implements migrateMaps operation.
|
|
||||||
//
|
|
||||||
// Perform maps migration.
|
|
||||||
//
|
|
||||||
// POST /migrate-maps
|
|
||||||
MigrateMaps(ctx context.Context) error
|
|
||||||
// ReleaseSubmissions implements releaseSubmissions operation.
|
// ReleaseSubmissions implements releaseSubmissions operation.
|
||||||
//
|
//
|
||||||
// Release a set of uploaded maps.
|
// Release a set of uploaded maps.
|
||||||
|
|||||||
@@ -40,16 +40,6 @@ func (UnimplementedHandler) ActionMapfixRequestChanges(ctx context.Context, para
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixResetSubmitting implements actionMapfixResetSubmitting operation.
|
|
||||||
//
|
|
||||||
// Role Submitter manually resets submitting softlock and changes status from Submitting ->
|
|
||||||
// UnderConstruction.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/reset-submitting
|
|
||||||
func (UnimplementedHandler) ActionMapfixResetSubmitting(ctx context.Context, params ActionMapfixResetSubmittingParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixRetryValidate implements actionMapfixRetryValidate operation.
|
// ActionMapfixRetryValidate implements actionMapfixRetryValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
@@ -68,21 +58,12 @@ func (UnimplementedHandler) ActionMapfixRevoke(ctx context.Context, params Actio
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionMapfixTriggerSubmit implements actionMapfixTriggerSubmit operation.
|
// ActionMapfixSubmit implements actionMapfixSubmit operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitting.
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
//
|
//
|
||||||
// POST /mapfixes/{MapfixID}/status/trigger-submit
|
// POST /mapfixes/{MapfixID}/status/submit
|
||||||
func (UnimplementedHandler) ActionMapfixTriggerSubmit(ctx context.Context, params ActionMapfixTriggerSubmitParams) error {
|
func (UnimplementedHandler) ActionMapfixSubmit(ctx context.Context, params ActionMapfixSubmitParams) error {
|
||||||
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
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,16 +121,6 @@ func (UnimplementedHandler) ActionSubmissionRequestChanges(ctx context.Context,
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionResetSubmitting implements actionSubmissionResetSubmitting operation.
|
|
||||||
//
|
|
||||||
// Role Submitter manually resets submitting softlock and changes status from Submitting ->
|
|
||||||
// UnderConstruction.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/reset-submitting
|
|
||||||
func (UnimplementedHandler) ActionSubmissionResetSubmitting(ctx context.Context, params ActionSubmissionResetSubmittingParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
// ActionSubmissionRetryValidate implements actionSubmissionRetryValidate operation.
|
||||||
//
|
//
|
||||||
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
@@ -168,21 +139,12 @@ func (UnimplementedHandler) ActionSubmissionRevoke(ctx context.Context, params A
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionSubmissionTriggerSubmit implements actionSubmissionTriggerSubmit operation.
|
// ActionSubmissionSubmit implements actionSubmissionSubmit operation.
|
||||||
//
|
//
|
||||||
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitting.
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
//
|
//
|
||||||
// POST /submissions/{SubmissionID}/status/trigger-submit
|
// POST /submissions/{SubmissionID}/status/submit
|
||||||
func (UnimplementedHandler) ActionSubmissionTriggerSubmit(ctx context.Context, params ActionSubmissionTriggerSubmitParams) error {
|
func (UnimplementedHandler) ActionSubmissionSubmit(ctx context.Context, params ActionSubmissionSubmitParams) error {
|
||||||
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
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,15 +184,6 @@ func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixTrigger
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMapfixAuditComment implements createMapfixAuditComment operation.
|
|
||||||
//
|
|
||||||
// Post a comment to the audit log.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/comment
|
|
||||||
func (UnimplementedHandler) CreateMapfixAuditComment(ctx context.Context, req CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateScript implements createScript operation.
|
// CreateScript implements createScript operation.
|
||||||
//
|
//
|
||||||
// Create a new script.
|
// Create a new script.
|
||||||
@@ -258,24 +211,6 @@ func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *Submissio
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSubmissionAdmin implements createSubmissionAdmin operation.
|
|
||||||
//
|
|
||||||
// Trigger the validator to create a new submission.
|
|
||||||
//
|
|
||||||
// POST /submissions-admin
|
|
||||||
func (UnimplementedHandler) CreateSubmissionAdmin(ctx context.Context, req *SubmissionTriggerCreate) (r *OperationID, _ error) {
|
|
||||||
return r, ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.
|
|
||||||
//
|
|
||||||
// Post a comment to the audit log.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/comment
|
|
||||||
func (UnimplementedHandler) CreateSubmissionAuditComment(ctx context.Context, req CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteScript implements deleteScript operation.
|
// DeleteScript implements deleteScript operation.
|
||||||
//
|
//
|
||||||
// Delete the specified script by ID.
|
// Delete the specified script by ID.
|
||||||
@@ -294,15 +229,6 @@ func (UnimplementedHandler) DeleteScriptPolicy(ctx context.Context, params Delet
|
|||||||
return ht.ErrNotImplemented
|
return ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadMapAsset implements downloadMapAsset operation.
|
|
||||||
//
|
|
||||||
// Download the map asset.
|
|
||||||
//
|
|
||||||
// GET /maps/{MapID}/download
|
|
||||||
func (UnimplementedHandler) DownloadMapAsset(ctx context.Context, params DownloadMapAssetParams) (r DownloadMapAssetOK, _ error) {
|
|
||||||
return r, ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMap implements getMap operation.
|
// GetMap implements getMap operation.
|
||||||
//
|
//
|
||||||
// Retrieve map with ID.
|
// Retrieve map with ID.
|
||||||
@@ -357,21 +283,12 @@ func (UnimplementedHandler) GetSubmission(ctx context.Context, params GetSubmiss
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListMapfixAuditEvents implements listMapfixAuditEvents operation.
|
|
||||||
//
|
|
||||||
// Retrieve a list of audit events.
|
|
||||||
//
|
|
||||||
// GET /mapfixes/{MapfixID}/audit-events
|
|
||||||
func (UnimplementedHandler) ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) (r []AuditEvent, _ error) {
|
|
||||||
return r, ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMapfixes implements listMapfixes operation.
|
// ListMapfixes implements listMapfixes operation.
|
||||||
//
|
//
|
||||||
// Get list of mapfixes.
|
// Get list of mapfixes.
|
||||||
//
|
//
|
||||||
// GET /mapfixes
|
// GET /mapfixes
|
||||||
func (UnimplementedHandler) ListMapfixes(ctx context.Context, params ListMapfixesParams) (r *Mapfixes, _ error) {
|
func (UnimplementedHandler) ListMapfixes(ctx context.Context, params ListMapfixesParams) (r []Mapfix, _ error) {
|
||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,33 +319,15 @@ func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsP
|
|||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListSubmissionAuditEvents implements listSubmissionAuditEvents operation.
|
|
||||||
//
|
|
||||||
// Retrieve a list of audit events.
|
|
||||||
//
|
|
||||||
// GET /submissions/{SubmissionID}/audit-events
|
|
||||||
func (UnimplementedHandler) ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) (r []AuditEvent, _ error) {
|
|
||||||
return r, ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListSubmissions implements listSubmissions operation.
|
// ListSubmissions implements listSubmissions operation.
|
||||||
//
|
//
|
||||||
// Get list of submissions.
|
// Get list of submissions.
|
||||||
//
|
//
|
||||||
// GET /submissions
|
// GET /submissions
|
||||||
func (UnimplementedHandler) ListSubmissions(ctx context.Context, params ListSubmissionsParams) (r *Submissions, _ error) {
|
func (UnimplementedHandler) ListSubmissions(ctx context.Context, params ListSubmissionsParams) (r []Submission, _ error) {
|
||||||
return r, ht.ErrNotImplemented
|
return r, ht.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// MigrateMaps implements migrateMaps operation.
|
|
||||||
//
|
|
||||||
// Perform maps migration.
|
|
||||||
//
|
|
||||||
// POST /migrate-maps
|
|
||||||
func (UnimplementedHandler) MigrateMaps(ctx context.Context) error {
|
|
||||||
return ht.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseSubmissions implements releaseSubmissions operation.
|
// ReleaseSubmissions implements releaseSubmissions operation.
|
||||||
//
|
//
|
||||||
// Release a set of uploaded maps.
|
// Release a set of uploaded maps.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,21 +2,15 @@ package cmds
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/auth"
|
"git.itzana.me/strafesnet/go-grpc/auth"
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps_extended"
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/users"
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/controller"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/roblox"
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/validator_controller"
|
"git.itzana.me/strafesnet/maps-service/pkg/service_internal"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/web_api"
|
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@@ -96,12 +90,6 @@ 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,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,67 +122,45 @@ func serve(ctx *cli.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
svc_inner := service.NewService(
|
svc := &service.Service{
|
||||||
db,
|
DB: db,
|
||||||
js,
|
Nats: js,
|
||||||
maps.NewMapsServiceClient(conn),
|
Client: maps.NewMapsServiceClient(conn),
|
||||||
users.NewUsersServiceClient(conn),
|
}
|
||||||
)
|
|
||||||
|
|
||||||
svc_external := web_api.NewService(
|
|
||||||
&svc_inner,
|
|
||||||
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()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
sec := web_api.SecurityHandler{
|
sec := service.SecurityHandler{
|
||||||
Client: auth.NewAuthServiceClient(conn),
|
Client: auth.NewAuthServiceClient(conn),
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_external, err := api.NewServer(&svc_external, sec, api.WithPathPrefix("/v1"))
|
srv, err := api.NewServer(svc, sec, api.WithPathPrefix("/v1"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Fatal("failed to initialize api server")
|
log.WithError(err).Fatal("failed to initialize api server")
|
||||||
}
|
}
|
||||||
|
|
||||||
grpcServer := grpc.NewServer()
|
svc2 := &service_internal.Service{
|
||||||
|
DB: db,
|
||||||
|
Nats: js,
|
||||||
|
}
|
||||||
|
|
||||||
maps_controller := controller.NewMapsController(&svc_inner)
|
srv2, err := internal.NewServer(svc2, internal.WithPathPrefix("/v1"))
|
||||||
maps_extended.RegisterMapsServiceServer(grpcServer,&maps_controller)
|
|
||||||
|
|
||||||
mapfix_controller := validator_controller.NewMapfixesController(&svc_inner)
|
|
||||||
operation_controller := validator_controller.NewOperationsController(&svc_inner)
|
|
||||||
script_controller := validator_controller.NewScriptsController(&svc_inner)
|
|
||||||
script_policy_controller := validator_controller.NewScriptPolicyController(&svc_inner)
|
|
||||||
submission_controller := validator_controller.NewSubmissionsController(&svc_inner)
|
|
||||||
|
|
||||||
validator.RegisterValidatorMapfixServiceServer(grpcServer,&mapfix_controller)
|
|
||||||
validator.RegisterValidatorOperationServiceServer(grpcServer,&operation_controller)
|
|
||||||
validator.RegisterValidatorScriptServiceServer(grpcServer,&script_controller)
|
|
||||||
validator.RegisterValidatorScriptPolicyServiceServer(grpcServer,&script_policy_controller)
|
|
||||||
validator.RegisterValidatorSubmissionServiceServer(grpcServer,&submission_controller)
|
|
||||||
|
|
||||||
port := ctx.Int("port-internal")
|
|
||||||
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("error", err).Fatalln("failed to net.Listen")
|
log.WithError(err).Fatal("failed to initialize api server")
|
||||||
}
|
}
|
||||||
// Channel to collect errors
|
// Channel to collect errors
|
||||||
errChan := make(chan error, 2)
|
errChan := make(chan error, 2)
|
||||||
|
|
||||||
// First server
|
// First server
|
||||||
go func(errChan chan error) {
|
go func(errChan chan error) {
|
||||||
errChan <- grpcServer.Serve(lis)
|
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port-internal")), srv2)
|
||||||
}(errChan)
|
}(errChan)
|
||||||
|
|
||||||
// Second server
|
// Second server
|
||||||
go func(errChan chan error) {
|
go func(errChan chan error) {
|
||||||
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv_external)
|
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv)
|
||||||
}(errChan)
|
}(errChan)
|
||||||
|
|
||||||
// Wait for the first error or completion of both tasks
|
// Wait for the first error or completion of both tasks
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps_extended"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
PageError = errors.New("Pagination required")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Maps struct {
|
|
||||||
*maps_extended.UnimplementedMapsServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMapsController(
|
|
||||||
inner *service.Service,
|
|
||||||
) Maps {
|
|
||||||
return Maps{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Maps) Create(ctx context.Context, request *maps_extended.MapCreate) (*maps_extended.MapId, error) {
|
|
||||||
id, err := svc.inner.CreateMap(ctx, model.Map{
|
|
||||||
ID: request.ID,
|
|
||||||
DisplayName: request.DisplayName,
|
|
||||||
Creator: request.Creator,
|
|
||||||
GameID: request.GameID,
|
|
||||||
Submitter: request.Submitter,
|
|
||||||
Date: time.Unix(request.Date, 0),
|
|
||||||
Thumbnail: request.Thumbnail,
|
|
||||||
AssetVersion: request.AssetVersion,
|
|
||||||
LoadCount: 0,
|
|
||||||
Modes: request.Modes,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &maps_extended.MapId{
|
|
||||||
ID: id,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Maps) Delete(ctx context.Context, request *maps_extended.MapId) (*maps_extended.NullResponse, error) {
|
|
||||||
err := svc.inner.DeleteMap(ctx, request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &maps_extended.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
func (svc *Maps) Get(ctx context.Context, request *maps_extended.MapId) (*maps_extended.MapResponse, error) {
|
|
||||||
item, err := svc.inner.GetMap(ctx, request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &maps_extended.MapResponse{
|
|
||||||
ID: item.ID,
|
|
||||||
DisplayName: item.DisplayName,
|
|
||||||
Creator: item.Creator,
|
|
||||||
GameID: uint32(item.GameID),
|
|
||||||
Date: item.Date.Unix(),
|
|
||||||
CreatedAt: item.CreatedAt.Unix(),
|
|
||||||
UpdatedAt: item.UpdatedAt.Unix(),
|
|
||||||
Submitter: uint64(item.Submitter),
|
|
||||||
Thumbnail: uint64(item.Thumbnail),
|
|
||||||
AssetVersion: uint64(item.AssetVersion),
|
|
||||||
LoadCount: item.LoadCount,
|
|
||||||
Modes: item.Modes,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
func (svc *Maps) GetList(ctx context.Context, request *maps_extended.MapIdList) (*maps_extended.MapList, error) {
|
|
||||||
items, err := svc.inner.GetMapList(ctx, request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := maps_extended.MapList{}
|
|
||||||
resp.Maps = make([]*maps_extended.MapResponse, len(items))
|
|
||||||
for i, item := range items {
|
|
||||||
resp.Maps[i] = &maps_extended.MapResponse{
|
|
||||||
ID: item.ID,
|
|
||||||
DisplayName: item.DisplayName,
|
|
||||||
Creator: item.Creator,
|
|
||||||
GameID: uint32(item.GameID),
|
|
||||||
Date: item.Date.Unix(),
|
|
||||||
CreatedAt: item.CreatedAt.Unix(),
|
|
||||||
UpdatedAt: item.UpdatedAt.Unix(),
|
|
||||||
Submitter: uint64(item.Submitter),
|
|
||||||
Thumbnail: uint64(item.Thumbnail),
|
|
||||||
AssetVersion: uint64(item.AssetVersion),
|
|
||||||
LoadCount: item.LoadCount,
|
|
||||||
Modes: item.Modes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
func (svc *Maps) List(ctx context.Context, request *maps_extended.ListRequest) (*maps_extended.MapList, error) {
|
|
||||||
if request.Page == nil {
|
|
||||||
return nil, PageError
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := service.NewMapFilter()
|
|
||||||
if request.Filter != nil {
|
|
||||||
if request.Filter.DisplayName != nil {
|
|
||||||
filter.SetDisplayName(*request.Filter.DisplayName)
|
|
||||||
}
|
|
||||||
if request.Filter.Creator != nil {
|
|
||||||
filter.SetCreator(*request.Filter.Creator)
|
|
||||||
}
|
|
||||||
if request.Filter.GameID != nil {
|
|
||||||
filter.SetGameID(*request.Filter.GameID)
|
|
||||||
}
|
|
||||||
if request.Filter.Submitter != nil {
|
|
||||||
filter.SetSubmitter(*request.Filter.Submitter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
items, err := svc.inner.ListMaps(ctx, filter, model.Page{
|
|
||||||
Number: int32(request.Page.Number),
|
|
||||||
Size: int32(request.Page.Size),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := maps_extended.MapList{}
|
|
||||||
resp.Maps = make([]*maps_extended.MapResponse, len(items))
|
|
||||||
for i, item := range items {
|
|
||||||
resp.Maps[i] = &maps_extended.MapResponse{
|
|
||||||
ID: item.ID,
|
|
||||||
DisplayName: item.DisplayName,
|
|
||||||
Creator: item.Creator,
|
|
||||||
GameID: uint32(item.GameID),
|
|
||||||
Date: item.Date.Unix(),
|
|
||||||
CreatedAt: item.CreatedAt.Unix(),
|
|
||||||
UpdatedAt: item.UpdatedAt.Unix(),
|
|
||||||
Submitter: uint64(item.Submitter),
|
|
||||||
Thumbnail: uint64(item.Thumbnail),
|
|
||||||
AssetVersion: uint64(item.AssetVersion),
|
|
||||||
LoadCount: item.LoadCount,
|
|
||||||
Modes: item.Modes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
func (svc *Maps) Update(ctx context.Context, request *maps_extended.MapUpdate) (*maps_extended.NullResponse, error) {
|
|
||||||
update := service.NewMapUpdate()
|
|
||||||
if request.DisplayName != nil {
|
|
||||||
update.SetDisplayName(*request.DisplayName)
|
|
||||||
}
|
|
||||||
if request.Creator != nil {
|
|
||||||
update.SetCreator(*request.Creator)
|
|
||||||
}
|
|
||||||
if request.GameID != nil {
|
|
||||||
update.SetGameID(*request.GameID)
|
|
||||||
}
|
|
||||||
if request.Date != nil {
|
|
||||||
update.SetDate(*request.Date)
|
|
||||||
}
|
|
||||||
if request.Submitter != nil {
|
|
||||||
update.SetSubmitter(*request.Submitter)
|
|
||||||
}
|
|
||||||
if request.Thumbnail != nil {
|
|
||||||
update.SetThumbnail(*request.Thumbnail)
|
|
||||||
}
|
|
||||||
if request.AssetVersion != nil {
|
|
||||||
update.SetAssetVersion(*request.AssetVersion)
|
|
||||||
}
|
|
||||||
if request.Modes != nil {
|
|
||||||
update.SetModes(*request.Modes)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := svc.inner.UpdateMap(ctx, request.ID, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &maps_extended.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Maps) IncrementLoadCount(ctx context.Context, request *maps_extended.MapId) (*maps_extended.NullResponse, error) {
|
|
||||||
err := svc.inner.IncrementMapLoadCount(ctx, request.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &maps_extended.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,6 @@ package datastore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,8 +22,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Datastore interface {
|
type Datastore interface {
|
||||||
AuditEvents() AuditEvents
|
|
||||||
Maps() Maps
|
|
||||||
Mapfixes() Mapfixes
|
Mapfixes() Mapfixes
|
||||||
Operations() Operations
|
Operations() Operations
|
||||||
Submissions() Submissions
|
Submissions() Submissions
|
||||||
@@ -33,24 +29,6 @@ type Datastore interface {
|
|||||||
ScriptPolicy() ScriptPolicy
|
ScriptPolicy() ScriptPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuditEvents interface {
|
|
||||||
Get(ctx context.Context, id int64) (model.AuditEvent, error)
|
|
||||||
Create(ctx context.Context, smap model.AuditEvent) (model.AuditEvent, error)
|
|
||||||
Update(ctx context.Context, id int64, values OptionalMap) error
|
|
||||||
Delete(ctx context.Context, id int64) error
|
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.AuditEvent, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Maps interface {
|
|
||||||
Get(ctx context.Context, id int64) (model.Map, error)
|
|
||||||
GetList(ctx context.Context, id []int64) ([]model.Map, error)
|
|
||||||
Create(ctx context.Context, smap model.Map) (model.Map, error)
|
|
||||||
Update(ctx context.Context, id int64, values OptionalMap) error
|
|
||||||
Delete(ctx context.Context, id int64) error
|
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Map, error)
|
|
||||||
IncrementLoadCount(ctx context.Context, id int64) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mapfixes interface {
|
type Mapfixes interface {
|
||||||
Get(ctx context.Context, id int64) (model.Mapfix, error)
|
Get(ctx context.Context, id int64) (model.Mapfix, error)
|
||||||
GetList(ctx context.Context, id []int64) ([]model.Mapfix, error)
|
GetList(ctx context.Context, id []int64) ([]model.Mapfix, error)
|
||||||
@@ -60,7 +38,7 @@ type Mapfixes interface {
|
|||||||
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.MapfixStatus, values OptionalMap) (model.Mapfix, error)
|
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.MapfixStatus, values OptionalMap) (model.Mapfix, error)
|
||||||
Delete(ctx context.Context, id int64) error
|
Delete(ctx context.Context, id int64) error
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Mapfix, error)
|
List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Mapfix, error)
|
||||||
ListWithTotal(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) (int64, []model.Mapfix, error)
|
ListRestricted(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort, submitter int64) ([]model.Mapfix, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Operations interface {
|
type Operations interface {
|
||||||
@@ -68,7 +46,6 @@ type Operations interface {
|
|||||||
Create(ctx context.Context, smap model.Operation) (model.Operation, error)
|
Create(ctx context.Context, smap model.Operation) (model.Operation, error)
|
||||||
Update(ctx context.Context, id int32, values OptionalMap) error
|
Update(ctx context.Context, id int32, values OptionalMap) error
|
||||||
Delete(ctx context.Context, id int32) error
|
Delete(ctx context.Context, id int32) error
|
||||||
CountSince(ctx context.Context, owner int64, since time.Time) (int64, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Submissions interface {
|
type Submissions interface {
|
||||||
@@ -80,7 +57,7 @@ type Submissions interface {
|
|||||||
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) (model.Submission, error)
|
IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.SubmissionStatus, values OptionalMap) (model.Submission, error)
|
||||||
Delete(ctx context.Context, id int64) error
|
Delete(ctx context.Context, id int64) error
|
||||||
List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Submission, error)
|
List(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) ([]model.Submission, error)
|
||||||
ListWithTotal(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort) (int64, []model.Submission, error)
|
ListRestricted(ctx context.Context, filters OptionalMap, page model.Page, sort ListSort, submitter int64) ([]model.Submission, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Scripts interface {
|
type Scripts interface {
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
package gormstore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AuditEvents struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *AuditEvents) Get(ctx context.Context, id int64) (model.AuditEvent, error) {
|
|
||||||
var mdl model.AuditEvent
|
|
||||||
if err := env.db.First(&mdl, id).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return mdl, datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return mdl, err
|
|
||||||
}
|
|
||||||
return mdl, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *AuditEvents) Create(ctx context.Context, smap model.AuditEvent) (model.AuditEvent, error) {
|
|
||||||
if err := env.db.Create(&smap).Error; err != nil {
|
|
||||||
return smap, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return smap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *AuditEvents) Update(ctx context.Context, id int64, values datastore.OptionalMap) error {
|
|
||||||
if err := env.db.Model(&model.AuditEvent{}).Where("id = ?", id).Updates(values.Map()).Error; err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *AuditEvents) Delete(ctx context.Context, id int64) error {
|
|
||||||
if err := env.db.Delete(&model.AuditEvent{}, id).Error; err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *AuditEvents) List(ctx context.Context, filters datastore.OptionalMap, page model.Page) ([]model.AuditEvent, error) {
|
|
||||||
var events []model.AuditEvent
|
|
||||||
if err := env.db.Where(filters.Map()).Order("id ASC").Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&events).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return events, nil
|
|
||||||
}
|
|
||||||
@@ -31,8 +31,6 @@ func New(ctx *cli.Context) (datastore.Datastore, error) {
|
|||||||
|
|
||||||
if ctx.Bool("migrate") {
|
if ctx.Bool("migrate") {
|
||||||
if err := db.AutoMigrate(
|
if err := db.AutoMigrate(
|
||||||
&model.AuditEvent{},
|
|
||||||
&model.Map{},
|
|
||||||
&model.Mapfix{},
|
&model.Mapfix{},
|
||||||
&model.Operation{},
|
&model.Operation{},
|
||||||
&model.Submission{},
|
&model.Submission{},
|
||||||
|
|||||||
@@ -9,14 +9,6 @@ type Gormstore struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Gormstore) AuditEvents() datastore.AuditEvents {
|
|
||||||
return &AuditEvents{db: g.db}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g Gormstore) Maps() datastore.Maps {
|
|
||||||
return &Maps{db: g.db}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g Gormstore) Mapfixes() datastore.Mapfixes {
|
func (g Gormstore) Mapfixes() datastore.Mapfixes {
|
||||||
return &Mapfixes{db: g.db}
|
return &Mapfixes{db: g.db}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,16 +55,11 @@ func (env *Mapfixes) Update(ctx context.Context, id int64, values datastore.Opti
|
|||||||
|
|
||||||
// the update can only occur if the status matches one of the provided values.
|
// the update can only occur if the status matches one of the provided values.
|
||||||
func (env *Mapfixes) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.MapfixStatus, values datastore.OptionalMap) error {
|
func (env *Mapfixes) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.MapfixStatus, values datastore.OptionalMap) error {
|
||||||
result := env.db.Model(&model.Mapfix{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map())
|
if err := env.db.Model(&model.Mapfix{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
||||||
if result.Error != nil {
|
if err == gorm.ErrRecordNotFound {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
return datastore.ErrNotExist
|
||||||
}
|
}
|
||||||
return result.Error
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return datastore.ErroNoRowsAffected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -136,18 +131,39 @@ func (env *Mapfixes) List(ctx context.Context, filters datastore.OptionalMap, pa
|
|||||||
return maps, nil
|
return maps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Mapfixes) ListWithTotal(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort) (int64, []model.Mapfix, error) {
|
func (env *Mapfixes) ListRestricted(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort, submitter int64) ([]model.Mapfix, error) {
|
||||||
// grab page items
|
var maps []model.Mapfix
|
||||||
maps, err := env.List(ctx, filters, page, sort)
|
|
||||||
if err != nil{
|
db := env.db
|
||||||
return 0, nil, err
|
|
||||||
|
switch sort {
|
||||||
|
case datastore.ListSortDisabled:
|
||||||
|
// No sort
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameAscending:
|
||||||
|
db=db.Order("display_name ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameDescending:
|
||||||
|
db=db.Order("display_name DESC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateAscending:
|
||||||
|
db=db.Order("created_at ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateDescending:
|
||||||
|
db=db.Order("created_at DESC")
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, datastore.ErrInvalidListSort
|
||||||
}
|
}
|
||||||
|
|
||||||
// count total with filters
|
if err := db.
|
||||||
var total int64
|
Where(filters.Map()).
|
||||||
if err := env.db.Model(&model.Mapfix{}).Where(filters.Map()).Count(&total).Error; err != nil {
|
Where("status_id NOT IN ? OR submitter = ? AND status_id IN ?",PrivateSubmissions,submitter,PrivateSubmissions).
|
||||||
return 0, nil, err
|
Offset(int((page.Number - 1) * page.Size)).
|
||||||
|
Limit(int(page.Size)).
|
||||||
|
Find(&maps).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return total, maps, nil
|
return maps, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
package gormstore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Maps struct {
|
|
||||||
db *gorm.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) Get(ctx context.Context, id int64) (model.Map, error) {
|
|
||||||
var mdl model.Map
|
|
||||||
if err := env.db.First(&mdl, id).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return mdl, datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return mdl, err
|
|
||||||
}
|
|
||||||
return mdl, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) GetList(ctx context.Context, id []int64) ([]model.Map, error) {
|
|
||||||
var mapList []model.Map
|
|
||||||
if err := env.db.Find(&mapList, "id IN ?", id).Error; err != nil {
|
|
||||||
return mapList, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) Create(ctx context.Context, smap model.Map) (model.Map, error) {
|
|
||||||
if err := env.db.Create(&smap).Error; err != nil {
|
|
||||||
return smap, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return smap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) Update(ctx context.Context, id int64, values datastore.OptionalMap) error {
|
|
||||||
if err := env.db.Model(&model.Map{}).Where("id = ?", id).Updates(values.Map()).Error; err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) IncrementLoadCount(ctx context.Context, id int64) error {
|
|
||||||
if err := env.db.Model(&model.Map{}).Where("id = ?", id).UpdateColumn("load_count", gorm.Expr("load_count + ?", 1)).Error; err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) Delete(ctx context.Context, id int64) error {
|
|
||||||
if err := env.db.Delete(&model.Map{}, id).Error; err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Maps) List(ctx context.Context, filters datastore.OptionalMap, page model.Page) ([]model.Map, error) {
|
|
||||||
var events []model.Map
|
|
||||||
if err := env.db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&events).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return events, nil
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ package gormstore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
@@ -54,12 +53,3 @@ func (env *Operations) Delete(ctx context.Context, id int32) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Operations) CountSince(ctx context.Context, owner int64, since time.Time) (int64, error) {
|
|
||||||
var count int64
|
|
||||||
if err := env.db.Model(&model.Operation{}).Where("owner = ? AND created_at > ?",owner,since).Count(&count).Error; err != nil {
|
|
||||||
return count, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ import (
|
|||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
PrivateSubmissions = []model.SubmissionStatus{
|
||||||
|
model.SubmissionStatusUnderConstruction,
|
||||||
|
model.SubmissionStatusChangesRequested,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Submissions struct {
|
type Submissions struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
@@ -55,16 +62,11 @@ func (env *Submissions) Update(ctx context.Context, id int64, values datastore.O
|
|||||||
|
|
||||||
// the update can only occur if the status matches one of the provided values.
|
// the update can only occur if the status matches one of the provided values.
|
||||||
func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
|
func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.SubmissionStatus, values datastore.OptionalMap) error {
|
||||||
result := env.db.Model(&model.Submission{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map())
|
if err := env.db.Model(&model.Submission{}).Where("id = ?", id).Where("status_id IN ?", statuses).Updates(values.Map()).Error; err != nil {
|
||||||
if result.Error != nil {
|
if err == gorm.ErrRecordNotFound {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
|
||||||
return datastore.ErrNotExist
|
return datastore.ErrNotExist
|
||||||
}
|
}
|
||||||
return result.Error
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return datastore.ErroNoRowsAffected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -136,18 +138,43 @@ func (env *Submissions) List(ctx context.Context, filters datastore.OptionalMap,
|
|||||||
return maps, nil
|
return maps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Submissions) ListWithTotal(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort) (int64, []model.Submission, error) {
|
func (env *Submissions) ListRestricted(ctx context.Context, filters datastore.OptionalMap, page model.Page, sort datastore.ListSort, submitter int64) ([]model.Submission, error) {
|
||||||
// grab page items
|
var maps []model.Submission
|
||||||
maps, err := env.List(ctx, filters, page, sort)
|
|
||||||
if err != nil{
|
db := env.db
|
||||||
return 0, nil, err
|
|
||||||
|
switch sort {
|
||||||
|
case datastore.ListSortDisabled:
|
||||||
|
// No sort
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameAscending:
|
||||||
|
db=db.Order("display_name ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDisplayNameDescending:
|
||||||
|
db=db.Order("display_name DESC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateAscending:
|
||||||
|
db=db.Order("created_at ASC")
|
||||||
|
break
|
||||||
|
case datastore.ListSortDateDescending:
|
||||||
|
db=db.Order("created_at DESC")
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, datastore.ErrInvalidListSort
|
||||||
}
|
}
|
||||||
|
|
||||||
// count total with filters
|
if err := db.
|
||||||
var total int64
|
Where(filters.Map()).
|
||||||
if err := env.db.Model(&model.Submission{}).Where(filters.Map()).Count(&total).Error; err != nil {
|
// In order to see submissions,
|
||||||
return 0, nil, err
|
// at least one of two criteria must be met:
|
||||||
|
// - You are the submitter
|
||||||
|
// - The submission is not under construction / changes requested
|
||||||
|
Where("status_id NOT IN ? OR submitter = ? AND status_id IN ?",PrivateSubmissions,submitter,PrivateSubmissions).
|
||||||
|
Offset(int((page.Number - 1) * page.Size)).
|
||||||
|
Limit(int(page.Size)).
|
||||||
|
Find(&maps).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return total, maps, nil
|
return maps, nil
|
||||||
}
|
}
|
||||||
|
|||||||
283
pkg/internal/oas_cfg_gen.go
Normal file
283
pkg/internal/oas_cfg_gen.go
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/metric"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
|
ht "github.com/ogen-go/ogen/http"
|
||||||
|
"github.com/ogen-go/ogen/middleware"
|
||||||
|
"github.com/ogen-go/ogen/ogenerrors"
|
||||||
|
"github.com/ogen-go/ogen/otelogen"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Allocate option closure once.
|
||||||
|
clientSpanKind = trace.WithSpanKind(trace.SpanKindClient)
|
||||||
|
// Allocate option closure once.
|
||||||
|
serverSpanKind = trace.WithSpanKind(trace.SpanKindServer)
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
optionFunc[C any] func(*C)
|
||||||
|
otelOptionFunc func(*otelConfig)
|
||||||
|
)
|
||||||
|
|
||||||
|
type otelConfig struct {
|
||||||
|
TracerProvider trace.TracerProvider
|
||||||
|
Tracer trace.Tracer
|
||||||
|
MeterProvider metric.MeterProvider
|
||||||
|
Meter metric.Meter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *otelConfig) initOTEL() {
|
||||||
|
if cfg.TracerProvider == nil {
|
||||||
|
cfg.TracerProvider = otel.GetTracerProvider()
|
||||||
|
}
|
||||||
|
if cfg.MeterProvider == nil {
|
||||||
|
cfg.MeterProvider = otel.GetMeterProvider()
|
||||||
|
}
|
||||||
|
cfg.Tracer = cfg.TracerProvider.Tracer(otelogen.Name,
|
||||||
|
trace.WithInstrumentationVersion(otelogen.SemVersion()),
|
||||||
|
)
|
||||||
|
cfg.Meter = cfg.MeterProvider.Meter(otelogen.Name,
|
||||||
|
metric.WithInstrumentationVersion(otelogen.SemVersion()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorHandler is error handler.
|
||||||
|
type ErrorHandler = ogenerrors.ErrorHandler
|
||||||
|
|
||||||
|
type serverConfig struct {
|
||||||
|
otelConfig
|
||||||
|
NotFound http.HandlerFunc
|
||||||
|
MethodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string)
|
||||||
|
ErrorHandler ErrorHandler
|
||||||
|
Prefix string
|
||||||
|
Middleware Middleware
|
||||||
|
MaxMultipartMemory int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerOption is server config option.
|
||||||
|
type ServerOption interface {
|
||||||
|
applyServer(*serverConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ServerOption = (optionFunc[serverConfig])(nil)
|
||||||
|
|
||||||
|
func (o optionFunc[C]) applyServer(c *C) {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ServerOption = (otelOptionFunc)(nil)
|
||||||
|
|
||||||
|
func (o otelOptionFunc) applyServer(c *serverConfig) {
|
||||||
|
o(&c.otelConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServerConfig(opts ...ServerOption) serverConfig {
|
||||||
|
cfg := serverConfig{
|
||||||
|
NotFound: http.NotFound,
|
||||||
|
MethodNotAllowed: func(w http.ResponseWriter, r *http.Request, allowed string) {
|
||||||
|
status := http.StatusMethodNotAllowed
|
||||||
|
if r.Method == "OPTIONS" {
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", allowed)
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
||||||
|
status = http.StatusNoContent
|
||||||
|
} else {
|
||||||
|
w.Header().Set("Allow", allowed)
|
||||||
|
}
|
||||||
|
w.WriteHeader(status)
|
||||||
|
},
|
||||||
|
ErrorHandler: ogenerrors.DefaultErrorHandler,
|
||||||
|
Middleware: nil,
|
||||||
|
MaxMultipartMemory: 32 << 20, // 32 MB
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt.applyServer(&cfg)
|
||||||
|
}
|
||||||
|
cfg.initOTEL()
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseServer struct {
|
||||||
|
cfg serverConfig
|
||||||
|
requests metric.Int64Counter
|
||||||
|
errors metric.Int64Counter
|
||||||
|
duration metric.Float64Histogram
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s baseServer) notFound(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s.cfg.NotFound(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s baseServer) notAllowed(w http.ResponseWriter, r *http.Request, allowed string) {
|
||||||
|
s.cfg.MethodNotAllowed(w, r, allowed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg serverConfig) baseServer() (s baseServer, err error) {
|
||||||
|
s = baseServer{cfg: cfg}
|
||||||
|
if s.requests, err = otelogen.ServerRequestCountCounter(s.cfg.Meter); err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
if s.errors, err = otelogen.ServerErrorsCountCounter(s.cfg.Meter); err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
if s.duration, err = otelogen.ServerDurationHistogram(s.cfg.Meter); err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type clientConfig struct {
|
||||||
|
otelConfig
|
||||||
|
Client ht.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientOption is client config option.
|
||||||
|
type ClientOption interface {
|
||||||
|
applyClient(*clientConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ClientOption = (optionFunc[clientConfig])(nil)
|
||||||
|
|
||||||
|
func (o optionFunc[C]) applyClient(c *C) {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ClientOption = (otelOptionFunc)(nil)
|
||||||
|
|
||||||
|
func (o otelOptionFunc) applyClient(c *clientConfig) {
|
||||||
|
o(&c.otelConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClientConfig(opts ...ClientOption) clientConfig {
|
||||||
|
cfg := clientConfig{
|
||||||
|
Client: http.DefaultClient,
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt.applyClient(&cfg)
|
||||||
|
}
|
||||||
|
cfg.initOTEL()
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseClient struct {
|
||||||
|
cfg clientConfig
|
||||||
|
requests metric.Int64Counter
|
||||||
|
errors metric.Int64Counter
|
||||||
|
duration metric.Float64Histogram
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg clientConfig) baseClient() (c baseClient, err error) {
|
||||||
|
c = baseClient{cfg: cfg}
|
||||||
|
if c.requests, err = otelogen.ClientRequestCountCounter(c.cfg.Meter); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
if c.errors, err = otelogen.ClientErrorsCountCounter(c.cfg.Meter); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
if c.duration, err = otelogen.ClientDurationHistogram(c.cfg.Meter); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option is config option.
|
||||||
|
type Option interface {
|
||||||
|
ServerOption
|
||||||
|
ClientOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
|
||||||
|
//
|
||||||
|
// If none is specified, the global provider is used.
|
||||||
|
func WithTracerProvider(provider trace.TracerProvider) Option {
|
||||||
|
return otelOptionFunc(func(cfg *otelConfig) {
|
||||||
|
if provider != nil {
|
||||||
|
cfg.TracerProvider = provider
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMeterProvider specifies a meter provider to use for creating a meter.
|
||||||
|
//
|
||||||
|
// If none is specified, the otel.GetMeterProvider() is used.
|
||||||
|
func WithMeterProvider(provider metric.MeterProvider) Option {
|
||||||
|
return otelOptionFunc(func(cfg *otelConfig) {
|
||||||
|
if provider != nil {
|
||||||
|
cfg.MeterProvider = provider
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithClient specifies http client to use.
|
||||||
|
func WithClient(client ht.Client) ClientOption {
|
||||||
|
return optionFunc[clientConfig](func(cfg *clientConfig) {
|
||||||
|
if client != nil {
|
||||||
|
cfg.Client = client
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNotFound specifies Not Found handler to use.
|
||||||
|
func WithNotFound(notFound http.HandlerFunc) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
if notFound != nil {
|
||||||
|
cfg.NotFound = notFound
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMethodNotAllowed specifies Method Not Allowed handler to use.
|
||||||
|
func WithMethodNotAllowed(methodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string)) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
if methodNotAllowed != nil {
|
||||||
|
cfg.MethodNotAllowed = methodNotAllowed
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithErrorHandler specifies error handler to use.
|
||||||
|
func WithErrorHandler(h ErrorHandler) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
if h != nil {
|
||||||
|
cfg.ErrorHandler = h
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPathPrefix specifies server path prefix.
|
||||||
|
func WithPathPrefix(prefix string) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
cfg.Prefix = prefix
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMiddleware specifies middlewares to use.
|
||||||
|
func WithMiddleware(m ...Middleware) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
switch len(m) {
|
||||||
|
case 0:
|
||||||
|
cfg.Middleware = nil
|
||||||
|
case 1:
|
||||||
|
cfg.Middleware = m[0]
|
||||||
|
default:
|
||||||
|
cfg.Middleware = middleware.ChainMiddlewares(m...)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMaxMultipartMemory specifies limit of memory for storing file parts.
|
||||||
|
// File parts which can't be stored in memory will be stored on disk in temporary files.
|
||||||
|
func WithMaxMultipartMemory(max int64) ServerOption {
|
||||||
|
return optionFunc[serverConfig](func(cfg *serverConfig) {
|
||||||
|
if max > 0 {
|
||||||
|
cfg.MaxMultipartMemory = max
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
1863
pkg/internal/oas_client_gen.go
Normal file
1863
pkg/internal/oas_client_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
2487
pkg/internal/oas_handlers_gen.go
Normal file
2487
pkg/internal/oas_handlers_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
1563
pkg/internal/oas_json_gen.go
Normal file
1563
pkg/internal/oas_json_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
42
pkg/internal/oas_labeler_gen.go
Normal file
42
pkg/internal/oas_labeler_gen.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Labeler is used to allow adding custom attributes to the server request metrics.
|
||||||
|
type Labeler struct {
|
||||||
|
attrs []attribute.KeyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add attributes to the Labeler.
|
||||||
|
func (l *Labeler) Add(attrs ...attribute.KeyValue) {
|
||||||
|
l.attrs = append(l.attrs, attrs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttributeSet returns the attributes added to the Labeler as an attribute.Set.
|
||||||
|
func (l *Labeler) AttributeSet() attribute.Set {
|
||||||
|
return attribute.NewSet(l.attrs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type labelerContextKey struct{}
|
||||||
|
|
||||||
|
// LabelerFromContext retrieves the Labeler from the provided context, if present.
|
||||||
|
//
|
||||||
|
// If no Labeler was found in the provided context a new, empty Labeler is returned and the second
|
||||||
|
// return value is false. In this case it is safe to use the Labeler but any attributes added to
|
||||||
|
// it will not be used.
|
||||||
|
func LabelerFromContext(ctx context.Context) (*Labeler, bool) {
|
||||||
|
if l, ok := ctx.Value(labelerContextKey{}).(*Labeler); ok {
|
||||||
|
return l, true
|
||||||
|
}
|
||||||
|
return &Labeler{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func contextWithLabeler(ctx context.Context, l *Labeler) context.Context {
|
||||||
|
return context.WithValue(ctx, labelerContextKey{}, l)
|
||||||
|
}
|
||||||
10
pkg/internal/oas_middleware_gen.go
Normal file
10
pkg/internal/oas_middleware_gen.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ogen-go/ogen/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Middleware is middleware type.
|
||||||
|
type Middleware = middleware.Middleware
|
||||||
25
pkg/internal/oas_operations_gen.go
Normal file
25
pkg/internal/oas_operations_gen.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
// OperationName is the ogen operation name
|
||||||
|
type OperationName = string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActionMapfixAcceptedOperation OperationName = "ActionMapfixAccepted"
|
||||||
|
ActionMapfixUploadedOperation OperationName = "ActionMapfixUploaded"
|
||||||
|
ActionMapfixValidatedOperation OperationName = "ActionMapfixValidated"
|
||||||
|
ActionOperationFailedOperation OperationName = "ActionOperationFailed"
|
||||||
|
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
|
||||||
|
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
|
||||||
|
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
|
||||||
|
CreateMapfixOperation OperationName = "CreateMapfix"
|
||||||
|
CreateScriptOperation OperationName = "CreateScript"
|
||||||
|
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
|
||||||
|
CreateSubmissionOperation OperationName = "CreateSubmission"
|
||||||
|
GetScriptOperation OperationName = "GetScript"
|
||||||
|
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
|
||||||
|
ListScriptsOperation OperationName = "ListScripts"
|
||||||
|
UpdateMapfixValidatedModelOperation OperationName = "UpdateMapfixValidatedModel"
|
||||||
|
UpdateSubmissionValidatedModelOperation OperationName = "UpdateSubmissionValidatedModel"
|
||||||
|
)
|
||||||
1852
pkg/internal/oas_parameters_gen.go
Normal file
1852
pkg/internal/oas_parameters_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
292
pkg/internal/oas_request_decoders_gen.go
Normal file
292
pkg/internal/oas_request_decoders_gen.go
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"mime"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-faster/errors"
|
||||||
|
"github.com/go-faster/jx"
|
||||||
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
|
"github.com/ogen-go/ogen/ogenerrors"
|
||||||
|
"github.com/ogen-go/ogen/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateMapfixRequest(r *http.Request) (
|
||||||
|
req *MapfixCreate,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = multierr.Append(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = multierr.Append(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request MapfixCreate
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return &request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateScriptRequest(r *http.Request) (
|
||||||
|
req *ScriptCreate,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = multierr.Append(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = multierr.Append(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request ScriptCreate
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return &request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateScriptPolicyRequest(r *http.Request) (
|
||||||
|
req *ScriptPolicyCreate,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = multierr.Append(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = multierr.Append(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request ScriptPolicyCreate
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
return &request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
|
||||||
|
req *SubmissionCreate,
|
||||||
|
close func() error,
|
||||||
|
rerr error,
|
||||||
|
) {
|
||||||
|
var closers []func() error
|
||||||
|
close = func() error {
|
||||||
|
var merr error
|
||||||
|
// Close in reverse order, to match defer behavior.
|
||||||
|
for i := len(closers) - 1; i >= 0; i-- {
|
||||||
|
c := closers[i]
|
||||||
|
merr = multierr.Append(merr, c())
|
||||||
|
}
|
||||||
|
return merr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if rerr != nil {
|
||||||
|
rerr = multierr.Append(rerr, close())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "parse media type")
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case ct == "application/json":
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
buf, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return req, close, validate.ErrBodyRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
d := jx.DecodeBytes(buf)
|
||||||
|
|
||||||
|
var request SubmissionCreate
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Decode(d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Skip(); err != io.EOF {
|
||||||
|
return errors.New("unexpected trailing data")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
err = &ogenerrors.DecodeBodyError{
|
||||||
|
ContentType: ct,
|
||||||
|
Body: buf,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
return req, close, err
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := request.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
return req, close, errors.Wrap(err, "validate")
|
||||||
|
}
|
||||||
|
return &request, close, nil
|
||||||
|
default:
|
||||||
|
return req, close, validate.InvalidContentType(ct)
|
||||||
|
}
|
||||||
|
}
|
||||||
68
pkg/internal/oas_request_encoders_gen.go
Normal file
68
pkg/internal/oas_request_encoders_gen.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-faster/jx"
|
||||||
|
|
||||||
|
ht "github.com/ogen-go/ogen/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encodeCreateMapfixRequest(
|
||||||
|
req *MapfixCreate,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateScriptRequest(
|
||||||
|
req *ScriptCreate,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateScriptPolicyRequest(
|
||||||
|
req *ScriptPolicyCreate,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateSubmissionRequest(
|
||||||
|
req *SubmissionCreate,
|
||||||
|
r *http.Request,
|
||||||
|
) error {
|
||||||
|
const contentType = "application/json"
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
{
|
||||||
|
req.Encode(e)
|
||||||
|
}
|
||||||
|
encoded := e.Bytes()
|
||||||
|
ht.SetBody(r, bytes.NewReader(encoded), contentType)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
1133
pkg/internal/oas_response_decoders_gen.go
Normal file
1133
pkg/internal/oas_response_decoders_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
210
pkg/internal/oas_response_encoders_gen.go
Normal file
210
pkg/internal/oas_response_encoders_gen.go
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-faster/errors"
|
||||||
|
"github.com/go-faster/jx"
|
||||||
|
"go.opentelemetry.io/otel/codes"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
|
ht "github.com/ogen-go/ogen/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encodeActionMapfixAcceptedResponse(response *ActionMapfixAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionMapfixUploadedResponse(response *ActionMapfixUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionMapfixValidatedResponse(response *ActionMapfixValidatedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionOperationFailedResponse(response *ActionOperationFailedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionSubmissionUploadedResponse(response *ActionSubmissionUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeActionSubmissionValidatedResponse(response *ActionSubmissionValidatedNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateMapfixResponse(response *MapfixID, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(201)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateScriptResponse(response *ScriptID, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(201)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateScriptPolicyResponse(response *ScriptPolicyID, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(201)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeCreateSubmissionResponse(response *SubmissionID, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(201)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(201))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeGetScriptResponse(response *Script, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeListScriptPolicyResponse(response []ScriptPolicy, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
e.ArrStart()
|
||||||
|
for _, elem := range response {
|
||||||
|
elem.Encode(e)
|
||||||
|
}
|
||||||
|
e.ArrEnd()
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeListScriptsResponse(response []Script, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(200)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(200))
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
e.ArrStart()
|
||||||
|
for _, elem := range response {
|
||||||
|
elem.Encode(e)
|
||||||
|
}
|
||||||
|
e.ArrEnd()
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeUpdateMapfixValidatedModelResponse(response *UpdateMapfixValidatedModelNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeUpdateSubmissionValidatedModelResponse(response *UpdateSubmissionValidatedModelNoContent, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.WriteHeader(204)
|
||||||
|
span.SetStatus(codes.Ok, http.StatusText(204))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeErrorResponse(response *ErrorStatusCode, w http.ResponseWriter, span trace.Span) error {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
code := response.StatusCode
|
||||||
|
if code == 0 {
|
||||||
|
// Set default status code.
|
||||||
|
code = http.StatusOK
|
||||||
|
}
|
||||||
|
w.WriteHeader(code)
|
||||||
|
if st := http.StatusText(code); code >= http.StatusBadRequest {
|
||||||
|
span.SetStatus(codes.Error, st)
|
||||||
|
} else {
|
||||||
|
span.SetStatus(codes.Ok, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
e := new(jx.Encoder)
|
||||||
|
response.Response.Encode(e)
|
||||||
|
if _, err := e.WriteTo(w); err != nil {
|
||||||
|
return errors.Wrap(err, "write")
|
||||||
|
}
|
||||||
|
|
||||||
|
if code >= http.StatusInternalServerError {
|
||||||
|
return errors.Wrapf(ht.ErrInternalServerErrorResponse, "code: %d, message: %s", code, http.StatusText(code))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
1149
pkg/internal/oas_router_gen.go
Normal file
1149
pkg/internal/oas_router_gen.go
Normal file
File diff suppressed because it is too large
Load Diff
665
pkg/internal/oas_schemas_gen.go
Normal file
665
pkg/internal/oas_schemas_gen.go
Normal file
@@ -0,0 +1,665 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *ErrorStatusCode) Error() string {
|
||||||
|
return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixAcceptedNoContent is response for ActionMapfixAccepted operation.
|
||||||
|
type ActionMapfixAcceptedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionMapfixUploadedNoContent is response for ActionMapfixUploaded operation.
|
||||||
|
type ActionMapfixUploadedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionMapfixValidatedNoContent is response for ActionMapfixValidated operation.
|
||||||
|
type ActionMapfixValidatedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionOperationFailedNoContent is response for ActionOperationFailed operation.
|
||||||
|
type ActionOperationFailedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
|
||||||
|
type ActionSubmissionAcceptedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionUploadedNoContent is response for ActionSubmissionUploaded operation.
|
||||||
|
type ActionSubmissionUploadedNoContent struct{}
|
||||||
|
|
||||||
|
// ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation.
|
||||||
|
type ActionSubmissionValidatedNoContent struct{}
|
||||||
|
|
||||||
|
// Represents error object.
|
||||||
|
// Ref: #/components/schemas/Error
|
||||||
|
type Error struct {
|
||||||
|
Code int64 `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCode returns the value of Code.
|
||||||
|
func (s *Error) GetCode() int64 {
|
||||||
|
return s.Code
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMessage returns the value of Message.
|
||||||
|
func (s *Error) GetMessage() string {
|
||||||
|
return s.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCode sets the value of Code.
|
||||||
|
func (s *Error) SetCode(val int64) {
|
||||||
|
s.Code = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMessage sets the value of Message.
|
||||||
|
func (s *Error) SetMessage(val string) {
|
||||||
|
s.Message = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorStatusCode wraps Error with StatusCode.
|
||||||
|
type ErrorStatusCode struct {
|
||||||
|
StatusCode int
|
||||||
|
Response Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStatusCode returns the value of StatusCode.
|
||||||
|
func (s *ErrorStatusCode) GetStatusCode() int {
|
||||||
|
return s.StatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResponse returns the value of Response.
|
||||||
|
func (s *ErrorStatusCode) GetResponse() Error {
|
||||||
|
return s.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusCode sets the value of StatusCode.
|
||||||
|
func (s *ErrorStatusCode) SetStatusCode(val int) {
|
||||||
|
s.StatusCode = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResponse sets the value of Response.
|
||||||
|
func (s *ErrorStatusCode) SetResponse(val Error) {
|
||||||
|
s.Response = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/MapfixCreate
|
||||||
|
type MapfixCreate struct {
|
||||||
|
OperationID int32 `json:"OperationID"`
|
||||||
|
AssetOwner int64 `json:"AssetOwner"`
|
||||||
|
DisplayName string `json:"DisplayName"`
|
||||||
|
Creator string `json:"Creator"`
|
||||||
|
GameID int32 `json:"GameID"`
|
||||||
|
AssetID int64 `json:"AssetID"`
|
||||||
|
AssetVersion int64 `json:"AssetVersion"`
|
||||||
|
TargetAssetID int64 `json:"TargetAssetID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOperationID returns the value of OperationID.
|
||||||
|
func (s *MapfixCreate) GetOperationID() int32 {
|
||||||
|
return s.OperationID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetOwner returns the value of AssetOwner.
|
||||||
|
func (s *MapfixCreate) GetAssetOwner() int64 {
|
||||||
|
return s.AssetOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDisplayName returns the value of DisplayName.
|
||||||
|
func (s *MapfixCreate) GetDisplayName() string {
|
||||||
|
return s.DisplayName
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCreator returns the value of Creator.
|
||||||
|
func (s *MapfixCreate) GetCreator() string {
|
||||||
|
return s.Creator
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGameID returns the value of GameID.
|
||||||
|
func (s *MapfixCreate) GetGameID() int32 {
|
||||||
|
return s.GameID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetID returns the value of AssetID.
|
||||||
|
func (s *MapfixCreate) GetAssetID() int64 {
|
||||||
|
return s.AssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetVersion returns the value of AssetVersion.
|
||||||
|
func (s *MapfixCreate) GetAssetVersion() int64 {
|
||||||
|
return s.AssetVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTargetAssetID returns the value of TargetAssetID.
|
||||||
|
func (s *MapfixCreate) GetTargetAssetID() int64 {
|
||||||
|
return s.TargetAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOperationID sets the value of OperationID.
|
||||||
|
func (s *MapfixCreate) SetOperationID(val int32) {
|
||||||
|
s.OperationID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetOwner sets the value of AssetOwner.
|
||||||
|
func (s *MapfixCreate) SetAssetOwner(val int64) {
|
||||||
|
s.AssetOwner = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDisplayName sets the value of DisplayName.
|
||||||
|
func (s *MapfixCreate) SetDisplayName(val string) {
|
||||||
|
s.DisplayName = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCreator sets the value of Creator.
|
||||||
|
func (s *MapfixCreate) SetCreator(val string) {
|
||||||
|
s.Creator = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGameID sets the value of GameID.
|
||||||
|
func (s *MapfixCreate) SetGameID(val int32) {
|
||||||
|
s.GameID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetID sets the value of AssetID.
|
||||||
|
func (s *MapfixCreate) SetAssetID(val int64) {
|
||||||
|
s.AssetID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetVersion sets the value of AssetVersion.
|
||||||
|
func (s *MapfixCreate) SetAssetVersion(val int64) {
|
||||||
|
s.AssetVersion = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTargetAssetID sets the value of TargetAssetID.
|
||||||
|
func (s *MapfixCreate) SetTargetAssetID(val int64) {
|
||||||
|
s.TargetAssetID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/MapfixID
|
||||||
|
type MapfixID struct {
|
||||||
|
MapfixID int64 `json:"MapfixID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMapfixID returns the value of MapfixID.
|
||||||
|
func (s *MapfixID) GetMapfixID() int64 {
|
||||||
|
return s.MapfixID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMapfixID sets the value of MapfixID.
|
||||||
|
func (s *MapfixID) SetMapfixID(val int64) {
|
||||||
|
s.MapfixID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOptInt32 returns new OptInt32 with value set to v.
|
||||||
|
func NewOptInt32(v int32) OptInt32 {
|
||||||
|
return OptInt32{
|
||||||
|
Value: v,
|
||||||
|
Set: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptInt32 is optional int32.
|
||||||
|
type OptInt32 struct {
|
||||||
|
Value int32
|
||||||
|
Set bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns true if OptInt32 was set.
|
||||||
|
func (o OptInt32) IsSet() bool { return o.Set }
|
||||||
|
|
||||||
|
// Reset unsets value.
|
||||||
|
func (o *OptInt32) Reset() {
|
||||||
|
var v int32
|
||||||
|
o.Value = v
|
||||||
|
o.Set = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo sets value to v.
|
||||||
|
func (o *OptInt32) SetTo(v int32) {
|
||||||
|
o.Set = true
|
||||||
|
o.Value = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns value and boolean that denotes whether value was set.
|
||||||
|
func (o OptInt32) Get() (v int32, ok bool) {
|
||||||
|
if !o.Set {
|
||||||
|
return v, false
|
||||||
|
}
|
||||||
|
return o.Value, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns value if set, or given parameter if does not.
|
||||||
|
func (o OptInt32) Or(d int32) int32 {
|
||||||
|
if v, ok := o.Get(); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOptInt64 returns new OptInt64 with value set to v.
|
||||||
|
func NewOptInt64(v int64) OptInt64 {
|
||||||
|
return OptInt64{
|
||||||
|
Value: v,
|
||||||
|
Set: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptInt64 is optional int64.
|
||||||
|
type OptInt64 struct {
|
||||||
|
Value int64
|
||||||
|
Set bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns true if OptInt64 was set.
|
||||||
|
func (o OptInt64) IsSet() bool { return o.Set }
|
||||||
|
|
||||||
|
// Reset unsets value.
|
||||||
|
func (o *OptInt64) Reset() {
|
||||||
|
var v int64
|
||||||
|
o.Value = v
|
||||||
|
o.Set = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo sets value to v.
|
||||||
|
func (o *OptInt64) SetTo(v int64) {
|
||||||
|
o.Set = true
|
||||||
|
o.Value = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns value and boolean that denotes whether value was set.
|
||||||
|
func (o OptInt64) Get() (v int64, ok bool) {
|
||||||
|
if !o.Set {
|
||||||
|
return v, false
|
||||||
|
}
|
||||||
|
return o.Value, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns value if set, or given parameter if does not.
|
||||||
|
func (o OptInt64) Or(d int64) int64 {
|
||||||
|
if v, ok := o.Get(); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOptString returns new OptString with value set to v.
|
||||||
|
func NewOptString(v string) OptString {
|
||||||
|
return OptString{
|
||||||
|
Value: v,
|
||||||
|
Set: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptString is optional string.
|
||||||
|
type OptString struct {
|
||||||
|
Value string
|
||||||
|
Set bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns true if OptString was set.
|
||||||
|
func (o OptString) IsSet() bool { return o.Set }
|
||||||
|
|
||||||
|
// Reset unsets value.
|
||||||
|
func (o *OptString) Reset() {
|
||||||
|
var v string
|
||||||
|
o.Value = v
|
||||||
|
o.Set = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo sets value to v.
|
||||||
|
func (o *OptString) SetTo(v string) {
|
||||||
|
o.Set = true
|
||||||
|
o.Value = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns value and boolean that denotes whether value was set.
|
||||||
|
func (o OptString) Get() (v string, ok bool) {
|
||||||
|
if !o.Set {
|
||||||
|
return v, false
|
||||||
|
}
|
||||||
|
return o.Value, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or returns value if set, or given parameter if does not.
|
||||||
|
func (o OptString) Or(d string) string {
|
||||||
|
if v, ok := o.Get(); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/Script
|
||||||
|
type Script struct {
|
||||||
|
ID int64 `json:"ID"`
|
||||||
|
Name string `json:"Name"`
|
||||||
|
Hash string `json:"Hash"`
|
||||||
|
Source string `json:"Source"`
|
||||||
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID int64 `json:"ResourceID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID returns the value of ID.
|
||||||
|
func (s *Script) GetID() int64 {
|
||||||
|
return s.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the value of Name.
|
||||||
|
func (s *Script) GetName() string {
|
||||||
|
return s.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHash returns the value of Hash.
|
||||||
|
func (s *Script) GetHash() string {
|
||||||
|
return s.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSource returns the value of Source.
|
||||||
|
func (s *Script) GetSource() string {
|
||||||
|
return s.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceType returns the value of ResourceType.
|
||||||
|
func (s *Script) GetResourceType() int32 {
|
||||||
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *Script) GetResourceID() int64 {
|
||||||
|
return s.ResourceID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetID sets the value of ID.
|
||||||
|
func (s *Script) SetID(val int64) {
|
||||||
|
s.ID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the value of Name.
|
||||||
|
func (s *Script) SetName(val string) {
|
||||||
|
s.Name = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHash sets the value of Hash.
|
||||||
|
func (s *Script) SetHash(val string) {
|
||||||
|
s.Hash = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSource sets the value of Source.
|
||||||
|
func (s *Script) SetSource(val string) {
|
||||||
|
s.Source = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceType sets the value of ResourceType.
|
||||||
|
func (s *Script) SetResourceType(val int32) {
|
||||||
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *Script) SetResourceID(val int64) {
|
||||||
|
s.ResourceID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ScriptCreate
|
||||||
|
type ScriptCreate struct {
|
||||||
|
Name string `json:"Name"`
|
||||||
|
Source string `json:"Source"`
|
||||||
|
ResourceType int32 `json:"ResourceType"`
|
||||||
|
ResourceID OptInt64 `json:"ResourceID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the value of Name.
|
||||||
|
func (s *ScriptCreate) GetName() string {
|
||||||
|
return s.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSource returns the value of Source.
|
||||||
|
func (s *ScriptCreate) GetSource() string {
|
||||||
|
return s.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceType returns the value of ResourceType.
|
||||||
|
func (s *ScriptCreate) GetResourceType() int32 {
|
||||||
|
return s.ResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceID returns the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) GetResourceID() OptInt64 {
|
||||||
|
return s.ResourceID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the value of Name.
|
||||||
|
func (s *ScriptCreate) SetName(val string) {
|
||||||
|
s.Name = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSource sets the value of Source.
|
||||||
|
func (s *ScriptCreate) SetSource(val string) {
|
||||||
|
s.Source = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceType sets the value of ResourceType.
|
||||||
|
func (s *ScriptCreate) SetResourceType(val int32) {
|
||||||
|
s.ResourceType = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetResourceID sets the value of ResourceID.
|
||||||
|
func (s *ScriptCreate) SetResourceID(val OptInt64) {
|
||||||
|
s.ResourceID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ScriptID
|
||||||
|
type ScriptID struct {
|
||||||
|
ScriptID int64 `json:"ScriptID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetScriptID returns the value of ScriptID.
|
||||||
|
func (s *ScriptID) GetScriptID() int64 {
|
||||||
|
return s.ScriptID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetScriptID sets the value of ScriptID.
|
||||||
|
func (s *ScriptID) SetScriptID(val int64) {
|
||||||
|
s.ScriptID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ScriptPolicy
|
||||||
|
type ScriptPolicy struct {
|
||||||
|
ID int64 `json:"ID"`
|
||||||
|
FromScriptHash string `json:"FromScriptHash"`
|
||||||
|
ToScriptID int64 `json:"ToScriptID"`
|
||||||
|
Policy int32 `json:"Policy"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID returns the value of ID.
|
||||||
|
func (s *ScriptPolicy) GetID() int64 {
|
||||||
|
return s.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFromScriptHash returns the value of FromScriptHash.
|
||||||
|
func (s *ScriptPolicy) GetFromScriptHash() string {
|
||||||
|
return s.FromScriptHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetToScriptID returns the value of ToScriptID.
|
||||||
|
func (s *ScriptPolicy) GetToScriptID() int64 {
|
||||||
|
return s.ToScriptID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPolicy returns the value of Policy.
|
||||||
|
func (s *ScriptPolicy) GetPolicy() int32 {
|
||||||
|
return s.Policy
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetID sets the value of ID.
|
||||||
|
func (s *ScriptPolicy) SetID(val int64) {
|
||||||
|
s.ID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFromScriptHash sets the value of FromScriptHash.
|
||||||
|
func (s *ScriptPolicy) SetFromScriptHash(val string) {
|
||||||
|
s.FromScriptHash = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToScriptID sets the value of ToScriptID.
|
||||||
|
func (s *ScriptPolicy) SetToScriptID(val int64) {
|
||||||
|
s.ToScriptID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPolicy sets the value of Policy.
|
||||||
|
func (s *ScriptPolicy) SetPolicy(val int32) {
|
||||||
|
s.Policy = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ScriptPolicyCreate
|
||||||
|
type ScriptPolicyCreate struct {
|
||||||
|
FromScriptID int64 `json:"FromScriptID"`
|
||||||
|
ToScriptID int64 `json:"ToScriptID"`
|
||||||
|
Policy int32 `json:"Policy"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFromScriptID returns the value of FromScriptID.
|
||||||
|
func (s *ScriptPolicyCreate) GetFromScriptID() int64 {
|
||||||
|
return s.FromScriptID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetToScriptID returns the value of ToScriptID.
|
||||||
|
func (s *ScriptPolicyCreate) GetToScriptID() int64 {
|
||||||
|
return s.ToScriptID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPolicy returns the value of Policy.
|
||||||
|
func (s *ScriptPolicyCreate) GetPolicy() int32 {
|
||||||
|
return s.Policy
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFromScriptID sets the value of FromScriptID.
|
||||||
|
func (s *ScriptPolicyCreate) SetFromScriptID(val int64) {
|
||||||
|
s.FromScriptID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToScriptID sets the value of ToScriptID.
|
||||||
|
func (s *ScriptPolicyCreate) SetToScriptID(val int64) {
|
||||||
|
s.ToScriptID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPolicy sets the value of Policy.
|
||||||
|
func (s *ScriptPolicyCreate) SetPolicy(val int32) {
|
||||||
|
s.Policy = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/ScriptPolicyID
|
||||||
|
type ScriptPolicyID struct {
|
||||||
|
ScriptPolicyID int64 `json:"ScriptPolicyID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetScriptPolicyID returns the value of ScriptPolicyID.
|
||||||
|
func (s *ScriptPolicyID) GetScriptPolicyID() int64 {
|
||||||
|
return s.ScriptPolicyID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetScriptPolicyID sets the value of ScriptPolicyID.
|
||||||
|
func (s *ScriptPolicyID) SetScriptPolicyID(val int64) {
|
||||||
|
s.ScriptPolicyID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/SubmissionCreate
|
||||||
|
type SubmissionCreate struct {
|
||||||
|
OperationID int32 `json:"OperationID"`
|
||||||
|
AssetOwner int64 `json:"AssetOwner"`
|
||||||
|
DisplayName string `json:"DisplayName"`
|
||||||
|
Creator string `json:"Creator"`
|
||||||
|
GameID int32 `json:"GameID"`
|
||||||
|
AssetID int64 `json:"AssetID"`
|
||||||
|
AssetVersion int64 `json:"AssetVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOperationID returns the value of OperationID.
|
||||||
|
func (s *SubmissionCreate) GetOperationID() int32 {
|
||||||
|
return s.OperationID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetOwner returns the value of AssetOwner.
|
||||||
|
func (s *SubmissionCreate) GetAssetOwner() int64 {
|
||||||
|
return s.AssetOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDisplayName returns the value of DisplayName.
|
||||||
|
func (s *SubmissionCreate) GetDisplayName() string {
|
||||||
|
return s.DisplayName
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCreator returns the value of Creator.
|
||||||
|
func (s *SubmissionCreate) GetCreator() string {
|
||||||
|
return s.Creator
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGameID returns the value of GameID.
|
||||||
|
func (s *SubmissionCreate) GetGameID() int32 {
|
||||||
|
return s.GameID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetID returns the value of AssetID.
|
||||||
|
func (s *SubmissionCreate) GetAssetID() int64 {
|
||||||
|
return s.AssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssetVersion returns the value of AssetVersion.
|
||||||
|
func (s *SubmissionCreate) GetAssetVersion() int64 {
|
||||||
|
return s.AssetVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOperationID sets the value of OperationID.
|
||||||
|
func (s *SubmissionCreate) SetOperationID(val int32) {
|
||||||
|
s.OperationID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetOwner sets the value of AssetOwner.
|
||||||
|
func (s *SubmissionCreate) SetAssetOwner(val int64) {
|
||||||
|
s.AssetOwner = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDisplayName sets the value of DisplayName.
|
||||||
|
func (s *SubmissionCreate) SetDisplayName(val string) {
|
||||||
|
s.DisplayName = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCreator sets the value of Creator.
|
||||||
|
func (s *SubmissionCreate) SetCreator(val string) {
|
||||||
|
s.Creator = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGameID sets the value of GameID.
|
||||||
|
func (s *SubmissionCreate) SetGameID(val int32) {
|
||||||
|
s.GameID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetID sets the value of AssetID.
|
||||||
|
func (s *SubmissionCreate) SetAssetID(val int64) {
|
||||||
|
s.AssetID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAssetVersion sets the value of AssetVersion.
|
||||||
|
func (s *SubmissionCreate) SetAssetVersion(val int64) {
|
||||||
|
s.AssetVersion = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: #/components/schemas/SubmissionID
|
||||||
|
type SubmissionID struct {
|
||||||
|
SubmissionID int64 `json:"SubmissionID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSubmissionID returns the value of SubmissionID.
|
||||||
|
func (s *SubmissionID) GetSubmissionID() int64 {
|
||||||
|
return s.SubmissionID
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSubmissionID sets the value of SubmissionID.
|
||||||
|
func (s *SubmissionID) SetSubmissionID(val int64) {
|
||||||
|
s.SubmissionID = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMapfixValidatedModelNoContent is response for UpdateMapfixValidatedModel operation.
|
||||||
|
type UpdateMapfixValidatedModelNoContent struct{}
|
||||||
|
|
||||||
|
// UpdateSubmissionValidatedModelNoContent is response for UpdateSubmissionValidatedModel operation.
|
||||||
|
type UpdateSubmissionValidatedModelNoContent struct{}
|
||||||
130
pkg/internal/oas_server_gen.go
Normal file
130
pkg/internal/oas_server_gen.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handler handles operations described by OpenAPI v3 specification.
|
||||||
|
type Handler interface {
|
||||||
|
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-failed
|
||||||
|
ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error
|
||||||
|
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-uploaded
|
||||||
|
ActionMapfixUploaded(ctx context.Context, params ActionMapfixUploadedParams) error
|
||||||
|
// ActionMapfixValidated implements actionMapfixValidated operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-validated
|
||||||
|
ActionMapfixValidated(ctx context.Context, params ActionMapfixValidatedParams) error
|
||||||
|
// ActionOperationFailed implements actionOperationFailed operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Fail an operation and write a StatusMessage.
|
||||||
|
//
|
||||||
|
// POST /operations/{OperationID}/status/operation-failed
|
||||||
|
ActionOperationFailed(ctx context.Context, params ActionOperationFailedParams) error
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
|
ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error
|
||||||
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
||||||
|
ActionSubmissionUploaded(ctx context.Context, params ActionSubmissionUploadedParams) error
|
||||||
|
// ActionSubmissionValidated implements actionSubmissionValidated operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-validated
|
||||||
|
ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error
|
||||||
|
// CreateMapfix implements createMapfix operation.
|
||||||
|
//
|
||||||
|
// Create a mapfix.
|
||||||
|
//
|
||||||
|
// POST /mapfixes
|
||||||
|
CreateMapfix(ctx context.Context, req *MapfixCreate) (*MapfixID, error)
|
||||||
|
// CreateScript implements createScript operation.
|
||||||
|
//
|
||||||
|
// Create a new script.
|
||||||
|
//
|
||||||
|
// POST /scripts
|
||||||
|
CreateScript(ctx context.Context, req *ScriptCreate) (*ScriptID, error)
|
||||||
|
// CreateScriptPolicy implements createScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Create a new script policy.
|
||||||
|
//
|
||||||
|
// POST /script-policy
|
||||||
|
CreateScriptPolicy(ctx context.Context, req *ScriptPolicyCreate) (*ScriptPolicyID, error)
|
||||||
|
// CreateSubmission implements createSubmission operation.
|
||||||
|
//
|
||||||
|
// Create a new submission.
|
||||||
|
//
|
||||||
|
// POST /submissions
|
||||||
|
CreateSubmission(ctx context.Context, req *SubmissionCreate) (*SubmissionID, error)
|
||||||
|
// GetScript implements getScript operation.
|
||||||
|
//
|
||||||
|
// Get the specified script by ID.
|
||||||
|
//
|
||||||
|
// GET /scripts/{ScriptID}
|
||||||
|
GetScript(ctx context.Context, params GetScriptParams) (*Script, error)
|
||||||
|
// ListScriptPolicy implements listScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Get list of script policies.
|
||||||
|
//
|
||||||
|
// GET /script-policy
|
||||||
|
ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) ([]ScriptPolicy, error)
|
||||||
|
// ListScripts implements listScripts operation.
|
||||||
|
//
|
||||||
|
// Get list of scripts.
|
||||||
|
//
|
||||||
|
// GET /scripts
|
||||||
|
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
|
||||||
|
// UpdateMapfixValidatedModel implements updateMapfixValidatedModel operation.
|
||||||
|
//
|
||||||
|
// Update validated model.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/validated-model
|
||||||
|
UpdateMapfixValidatedModel(ctx context.Context, params UpdateMapfixValidatedModelParams) error
|
||||||
|
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
|
||||||
|
//
|
||||||
|
// Update validated model.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
|
UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error
|
||||||
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
|
//
|
||||||
|
// Used for common default response.
|
||||||
|
NewError(ctx context.Context, err error) *ErrorStatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server implements http server based on OpenAPI v3 specification and
|
||||||
|
// calls Handler to handle requests.
|
||||||
|
type Server struct {
|
||||||
|
h Handler
|
||||||
|
baseServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServer creates new Server.
|
||||||
|
func NewServer(h Handler, opts ...ServerOption) (*Server, error) {
|
||||||
|
s, err := newServerConfig(opts...).baseServer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Server{
|
||||||
|
h: h,
|
||||||
|
baseServer: s,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
166
pkg/internal/oas_unimplemented_gen.go
Normal file
166
pkg/internal/oas_unimplemented_gen.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
ht "github.com/ogen-go/ogen/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UnimplementedHandler is no-op Handler which returns http.ErrNotImplemented.
|
||||||
|
type UnimplementedHandler struct{}
|
||||||
|
|
||||||
|
var _ Handler = UnimplementedHandler{}
|
||||||
|
|
||||||
|
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-failed
|
||||||
|
func (UnimplementedHandler) ActionMapfixAccepted(ctx context.Context, params ActionMapfixAcceptedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-uploaded
|
||||||
|
func (UnimplementedHandler) ActionMapfixUploaded(ctx context.Context, params ActionMapfixUploadedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixValidated implements actionMapfixValidated operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-validated
|
||||||
|
func (UnimplementedHandler) ActionMapfixValidated(ctx context.Context, params ActionMapfixValidatedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionOperationFailed implements actionOperationFailed operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Fail an operation and write a StatusMessage.
|
||||||
|
//
|
||||||
|
// POST /operations/{OperationID}/status/operation-failed
|
||||||
|
func (UnimplementedHandler) ActionOperationFailed(ctx context.Context, params ActionOperationFailedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
|
func (UnimplementedHandler) ActionSubmissionAccepted(ctx context.Context, params ActionSubmissionAcceptedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
||||||
|
func (UnimplementedHandler) ActionSubmissionUploaded(ctx context.Context, params ActionSubmissionUploadedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionValidated implements actionSubmissionValidated operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-validated
|
||||||
|
func (UnimplementedHandler) ActionSubmissionValidated(ctx context.Context, params ActionSubmissionValidatedParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMapfix implements createMapfix operation.
|
||||||
|
//
|
||||||
|
// Create a mapfix.
|
||||||
|
//
|
||||||
|
// POST /mapfixes
|
||||||
|
func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixCreate) (r *MapfixID, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateScript implements createScript operation.
|
||||||
|
//
|
||||||
|
// Create a new script.
|
||||||
|
//
|
||||||
|
// POST /scripts
|
||||||
|
func (UnimplementedHandler) CreateScript(ctx context.Context, req *ScriptCreate) (r *ScriptID, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateScriptPolicy implements createScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Create a new script policy.
|
||||||
|
//
|
||||||
|
// POST /script-policy
|
||||||
|
func (UnimplementedHandler) CreateScriptPolicy(ctx context.Context, req *ScriptPolicyCreate) (r *ScriptPolicyID, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSubmission implements createSubmission operation.
|
||||||
|
//
|
||||||
|
// Create a new submission.
|
||||||
|
//
|
||||||
|
// POST /submissions
|
||||||
|
func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *SubmissionCreate) (r *SubmissionID, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetScript implements getScript operation.
|
||||||
|
//
|
||||||
|
// Get the specified script by ID.
|
||||||
|
//
|
||||||
|
// GET /scripts/{ScriptID}
|
||||||
|
func (UnimplementedHandler) GetScript(ctx context.Context, params GetScriptParams) (r *Script, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListScriptPolicy implements listScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Get list of script policies.
|
||||||
|
//
|
||||||
|
// GET /script-policy
|
||||||
|
func (UnimplementedHandler) ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) (r []ScriptPolicy, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListScripts implements listScripts operation.
|
||||||
|
//
|
||||||
|
// Get list of scripts.
|
||||||
|
//
|
||||||
|
// GET /scripts
|
||||||
|
func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsParams) (r []Script, _ error) {
|
||||||
|
return r, ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMapfixValidatedModel implements updateMapfixValidatedModel operation.
|
||||||
|
//
|
||||||
|
// Update validated model.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/validated-model
|
||||||
|
func (UnimplementedHandler) UpdateMapfixValidatedModel(ctx context.Context, params UpdateMapfixValidatedModelParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSubmissionValidatedModel implements updateSubmissionValidatedModel operation.
|
||||||
|
//
|
||||||
|
// Update validated model.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
|
func (UnimplementedHandler) UpdateSubmissionValidatedModel(ctx context.Context, params UpdateSubmissionValidatedModelParams) error {
|
||||||
|
return ht.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
|
//
|
||||||
|
// Used for common default response.
|
||||||
|
func (UnimplementedHandler) NewError(ctx context.Context, err error) (r *ErrorStatusCode) {
|
||||||
|
r = new(ErrorStatusCode)
|
||||||
|
return r
|
||||||
|
}
|
||||||
259
pkg/internal/oas_validators_gen.go
Normal file
259
pkg/internal/oas_validators_gen.go
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
// Code generated by ogen, DO NOT EDIT.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-faster/errors"
|
||||||
|
|
||||||
|
"github.com/ogen-go/ogen/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *MapfixCreate) 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.DisplayName)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "DisplayName",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
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.Creator)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Creator",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Script) 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: 16,
|
||||||
|
MinLengthSet: true,
|
||||||
|
MaxLength: 16,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.Hash)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Hash",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 0,
|
||||||
|
MinLengthSet: false,
|
||||||
|
MaxLength: 1048576,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.Source)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Source",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ScriptCreate) 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: 1048576,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.Source)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Source",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ScriptPolicy) Validate() error {
|
||||||
|
if s == nil {
|
||||||
|
return validate.ErrNilPointer
|
||||||
|
}
|
||||||
|
|
||||||
|
var failures []validate.FieldError
|
||||||
|
if err := func() error {
|
||||||
|
if err := (validate.String{
|
||||||
|
MinLength: 16,
|
||||||
|
MinLengthSet: true,
|
||||||
|
MaxLength: 16,
|
||||||
|
MaxLengthSet: true,
|
||||||
|
Email: false,
|
||||||
|
Hostname: false,
|
||||||
|
Regex: nil,
|
||||||
|
}).Validate(string(s.FromScriptHash)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "FromScriptHash",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SubmissionCreate) 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.DisplayName)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "DisplayName",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
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.Creator)); err != nil {
|
||||||
|
return errors.Wrap(err, "string")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}(); err != nil {
|
||||||
|
failures = append(failures, validate.FieldError{
|
||||||
|
Name: "Creator",
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
return &validate.Error{Fields: failures}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"math"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const ValidatorUserID uint64 = uint64(math.MaxInt64)
|
|
||||||
|
|
||||||
type AuditEventType int32
|
|
||||||
|
|
||||||
// User clicked "Submit", "Accept" etc
|
|
||||||
const AuditEventTypeAction AuditEventType = 0
|
|
||||||
type AuditEventDataAction struct {
|
|
||||||
TargetStatus uint32 `json:"target_status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// User wrote a comment
|
|
||||||
const AuditEventTypeComment AuditEventType = 1
|
|
||||||
type AuditEventDataComment struct {
|
|
||||||
Comment string `json:"comment"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// User changed Model
|
|
||||||
const AuditEventTypeChangeModel AuditEventType = 2
|
|
||||||
type AuditEventDataChangeModel struct {
|
|
||||||
OldModelID uint64 `json:"old_model_id"`
|
|
||||||
OldModelVersion uint64 `json:"old_model_version"`
|
|
||||||
NewModelID uint64 `json:"new_model_id"`
|
|
||||||
NewModelVersion uint64 `json:"new_model_version"`
|
|
||||||
}
|
|
||||||
// Validator validates model
|
|
||||||
const AuditEventTypeChangeValidatedModel AuditEventType = 3
|
|
||||||
type AuditEventDataChangeValidatedModel struct {
|
|
||||||
ValidatedModelID uint64 `json:"validated_model_id"`
|
|
||||||
ValidatedModelVersion uint64 `json:"validated_model_version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// User changed DisplayName / Creator
|
|
||||||
const AuditEventTypeChangeDisplayName AuditEventType = 4
|
|
||||||
const AuditEventTypeChangeCreator AuditEventType = 5
|
|
||||||
type AuditEventDataChangeName struct {
|
|
||||||
OldName string `json:"old_name"`
|
|
||||||
NewName string `json:"new_name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validator had an error
|
|
||||||
const AuditEventTypeError AuditEventType = 6
|
|
||||||
type AuditEventDataError struct {
|
|
||||||
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 {
|
|
||||||
ID int64 `gorm:"primaryKey"`
|
|
||||||
CreatedAt time.Time
|
|
||||||
User uint64
|
|
||||||
ResourceType ResourceType // is this a submission or is it a mapfix
|
|
||||||
ResourceID int64 // submission / mapfix / map ID
|
|
||||||
EventType AuditEventType
|
|
||||||
EventData json.RawMessage `gorm:"type:jsonb"`
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type Map struct {
|
|
||||||
ID int64
|
|
||||||
DisplayName string
|
|
||||||
Creator string
|
|
||||||
GameID uint32
|
|
||||||
Date time.Time // Release date
|
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
Submitter uint64 // UserID of submitter
|
|
||||||
Thumbnail uint64 // AssetID of thumbnail
|
|
||||||
AssetVersion uint64 // Version number for LoadAssetVersion
|
|
||||||
LoadCount uint32 // How many times the map has been loaded
|
|
||||||
Modes uint32 // Number of modes (always at least one)
|
|
||||||
}
|
|
||||||
@@ -5,39 +5,36 @@ import "time"
|
|||||||
type MapfixStatus int32
|
type MapfixStatus int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Phase: Creation
|
// Phase: Final MapfixStatus
|
||||||
MapfixStatusUnderConstruction MapfixStatus = 0
|
MapfixStatusRejected MapfixStatus = 8
|
||||||
MapfixStatusChangesRequested MapfixStatus = 1
|
MapfixStatusUploaded MapfixStatus = 7 // uploaded to the group, final status for mapfixes
|
||||||
|
|
||||||
// Phase: Review
|
|
||||||
MapfixStatusSubmitting MapfixStatus = 2
|
|
||||||
MapfixStatusSubmitted MapfixStatus = 3
|
|
||||||
|
|
||||||
// Phase: Testing
|
// Phase: Testing
|
||||||
MapfixStatusAcceptedUnvalidated MapfixStatus = 4 // pending script review, can re-trigger validation
|
MapfixStatusUploading MapfixStatus = 6
|
||||||
MapfixStatusValidating MapfixStatus = 5
|
MapfixStatusValidated MapfixStatus = 5
|
||||||
MapfixStatusValidated MapfixStatus = 6
|
MapfixStatusValidating MapfixStatus = 4
|
||||||
MapfixStatusUploading MapfixStatus = 7
|
MapfixStatusAccepted MapfixStatus = 3 // pending script review, can re-trigger validation
|
||||||
|
|
||||||
// Phase: Final MapfixStatus
|
// Phase: Creation
|
||||||
MapfixStatusUploaded MapfixStatus = 8 // uploaded to the group, but pending release
|
MapfixStatusChangesRequested MapfixStatus = 2
|
||||||
MapfixStatusRejected MapfixStatus = 9
|
MapfixStatusSubmitted MapfixStatus = 1
|
||||||
|
MapfixStatusUnderConstruction MapfixStatus = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mapfix struct {
|
type Mapfix struct {
|
||||||
ID int64 `gorm:"primaryKey"`
|
ID int64 `gorm:"primaryKey"`
|
||||||
DisplayName string
|
DisplayName string
|
||||||
Creator string
|
Creator string
|
||||||
GameID uint32
|
GameID int32
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
Submitter uint64 // UserID
|
Submitter int64 // UserID
|
||||||
AssetID uint64
|
AssetID int64
|
||||||
AssetVersion uint64
|
AssetVersion int64
|
||||||
ValidatedAssetID uint64
|
ValidatedAssetID int64
|
||||||
ValidatedAssetVersion uint64
|
ValidatedAssetVersion int64
|
||||||
Completed bool // Has this version of the map been completed at least once on maptest
|
Completed bool // Has this version of the map been completed at least once on maptest
|
||||||
TargetAssetID uint64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
TargetAssetID int64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
||||||
StatusID MapfixStatus
|
StatusID MapfixStatus
|
||||||
Description string // mapfix description
|
StatusMessage string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,61 +7,42 @@ package model
|
|||||||
|
|
||||||
type CreateSubmissionRequest struct {
|
type CreateSubmissionRequest struct {
|
||||||
// operation_id is passed back in the response message
|
// operation_id is passed back in the response message
|
||||||
OperationID int32
|
OperationID int32
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
DisplayName string
|
|
||||||
Creator string
|
|
||||||
GameID uint32
|
|
||||||
Status uint32
|
|
||||||
Roles uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateMapfixRequest struct {
|
type CreateMapfixRequest struct {
|
||||||
OperationID int32
|
OperationID int32
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
TargetAssetID uint64
|
TargetAssetID int64
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type CheckSubmissionRequest struct{
|
|
||||||
SubmissionID int64
|
|
||||||
ModelID uint64
|
|
||||||
SkipChecks bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type CheckMapfixRequest struct{
|
|
||||||
MapfixID int64
|
|
||||||
ModelID uint64
|
|
||||||
SkipChecks bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidateSubmissionRequest struct {
|
type ValidateSubmissionRequest struct {
|
||||||
// submission_id is passed back in the response message
|
// submission_id is passed back in the response message
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
ModelVersion uint64
|
ModelVersion int64
|
||||||
ValidatedModelID *uint64 // optional value
|
ValidatedModelID *int64 // optional value
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidateMapfixRequest struct {
|
type ValidateMapfixRequest struct {
|
||||||
MapfixID int64
|
MapfixID int64
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
ModelVersion uint64
|
ModelVersion int64
|
||||||
ValidatedModelID *uint64 // optional value
|
ValidatedModelID *int64 // optional value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new map
|
// Create a new map
|
||||||
type UploadSubmissionRequest struct {
|
type UploadSubmissionRequest struct {
|
||||||
SubmissionID int64
|
SubmissionID int64
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
ModelVersion uint64
|
ModelVersion int64
|
||||||
ModelName string
|
ModelName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type UploadMapfixRequest struct {
|
type UploadMapfixRequest struct {
|
||||||
MapfixID int64
|
MapfixID int64
|
||||||
ModelID uint64
|
ModelID int64
|
||||||
ModelVersion uint64
|
ModelVersion int64
|
||||||
TargetAssetID uint64
|
TargetAssetID int64
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const (
|
|||||||
type Operation struct {
|
type Operation struct {
|
||||||
ID int32 `gorm:"primaryKey"`
|
ID int32 `gorm:"primaryKey"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
Owner uint64 // UserID
|
Owner int64 // UserID
|
||||||
StatusID OperationStatus
|
StatusID OperationStatus
|
||||||
StatusMessage string
|
StatusMessage string
|
||||||
Path string // redirect to view completed operation e.g. "/mapfixes/4"
|
Path string // redirect to view completed operation e.g. "/mapfixes/4"
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type ResourceType int32
|
|
||||||
const (
|
|
||||||
ResourceUnknown ResourceType = 0
|
|
||||||
ResourceMapfix ResourceType = 1
|
|
||||||
ResourceSubmission ResourceType = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
type Resource struct{
|
|
||||||
ID int64
|
|
||||||
Type ResourceType
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
// Submissions roles bitflag
|
|
||||||
type Roles int32
|
|
||||||
var (
|
|
||||||
RolesSubmissionUpload Roles = 1<<6
|
|
||||||
RolesSubmissionReview Roles = 1<<5
|
|
||||||
RolesSubmissionRelease Roles = 1<<4
|
|
||||||
RolesScriptWrite Roles = 1<<3
|
|
||||||
RolesMapfixUpload Roles = 1<<2
|
|
||||||
RolesMapfixReview Roles = 1<<1
|
|
||||||
RolesMapDownload Roles = 1<<0
|
|
||||||
RolesEmpty Roles = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
// StrafesNET group roles
|
|
||||||
type GroupRole int32
|
|
||||||
var (
|
|
||||||
// has ScriptWrite
|
|
||||||
RoleQuat GroupRole = 255
|
|
||||||
RoleItzaname GroupRole = 254
|
|
||||||
RoleStagingDeveloper GroupRole = 240
|
|
||||||
RolesAll Roles = ^RolesEmpty
|
|
||||||
// has SubmissionUpload
|
|
||||||
RoleMapAdmin GroupRole = 128
|
|
||||||
RolesMapAdmin Roles = RolesSubmissionRelease|RolesSubmissionUpload|RolesSubmissionReview|RolesMapCouncil
|
|
||||||
// has MapfixReview
|
|
||||||
RoleMapCouncil GroupRole = 64
|
|
||||||
RolesMapCouncil Roles = RolesMapfixReview|RolesMapfixUpload|RolesMapAccess
|
|
||||||
// access to downloading maps
|
|
||||||
RoleMapAccess GroupRole = 32
|
|
||||||
RolesMapAccess Roles = RolesMapDownload
|
|
||||||
)
|
|
||||||
@@ -23,6 +23,13 @@ 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
|
||||||
|
|||||||
@@ -5,39 +5,37 @@ import "time"
|
|||||||
type SubmissionStatus int32
|
type SubmissionStatus int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Phase: Creation
|
// Phase: Final SubmissionStatus
|
||||||
SubmissionStatusUnderConstruction SubmissionStatus = 0
|
SubmissionStatusReleased SubmissionStatus = 9
|
||||||
SubmissionStatusChangesRequested SubmissionStatus = 1
|
SubmissionStatusRejected SubmissionStatus = 8
|
||||||
|
|
||||||
// Phase: Review
|
|
||||||
SubmissionStatusSubmitting SubmissionStatus = 2
|
|
||||||
SubmissionStatusSubmitted SubmissionStatus = 3
|
|
||||||
|
|
||||||
// Phase: Testing
|
// Phase: Testing
|
||||||
SubmissionStatusAcceptedUnvalidated SubmissionStatus = 4 // pending script review, can re-trigger validation
|
SubmissionStatusUploaded SubmissionStatus = 7 // uploaded to the group, but pending release
|
||||||
SubmissionStatusValidating SubmissionStatus = 5
|
SubmissionStatusUploading SubmissionStatus = 6
|
||||||
SubmissionStatusValidated SubmissionStatus = 6
|
SubmissionStatusValidated SubmissionStatus = 5
|
||||||
SubmissionStatusUploading SubmissionStatus = 7
|
SubmissionStatusValidating SubmissionStatus = 4
|
||||||
SubmissionStatusUploaded SubmissionStatus = 8 // uploaded to the group, but pending release
|
SubmissionStatusAccepted SubmissionStatus = 3 // pending script review, can re-trigger validation
|
||||||
|
|
||||||
// Phase: Final SubmissionStatus
|
// Phase: Creation
|
||||||
SubmissionStatusRejected SubmissionStatus = 9
|
SubmissionStatusChangesRequested SubmissionStatus = 2
|
||||||
SubmissionStatusReleased SubmissionStatus = 10
|
SubmissionStatusSubmitted SubmissionStatus = 1
|
||||||
|
SubmissionStatusUnderConstruction SubmissionStatus = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
type Submission struct {
|
type Submission struct {
|
||||||
ID int64 `gorm:"primaryKey"`
|
ID int64 `gorm:"primaryKey"`
|
||||||
DisplayName string
|
DisplayName string
|
||||||
Creator string
|
Creator string
|
||||||
GameID uint32
|
GameID int32
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
Submitter uint64 // UserID
|
Submitter int64 // UserID
|
||||||
AssetID uint64
|
AssetID int64
|
||||||
AssetVersion uint64
|
AssetVersion int64
|
||||||
ValidatedAssetID uint64
|
ValidatedAssetID int64
|
||||||
ValidatedAssetVersion uint64
|
ValidatedAssetVersion int64
|
||||||
Completed bool // Has this version of the map been completed at least once on maptest
|
Completed bool // Has this version of the map been completed at least once on maptest
|
||||||
UploadedAssetID uint64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
UploadedAssetID int64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
|
||||||
StatusID SubmissionStatus
|
StatusID SubmissionStatus
|
||||||
|
StatusMessage string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
package roblox
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AssetMetadata struct {
|
|
||||||
MetadataType uint32 `json:"metadataType"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Struct equivalent to Rust's AssetLocationInfo
|
|
||||||
type AssetLocationInfo struct {
|
|
||||||
Location string `json:"location"`
|
|
||||||
RequestId string `json:"requestId"`
|
|
||||||
IsArchived bool `json:"isArchived"`
|
|
||||||
AssetTypeId uint32 `json:"assetTypeId"`
|
|
||||||
AssetMetadatas []AssetMetadata `json:"assetMetadatas"`
|
|
||||||
IsRecordable bool `json:"isRecordable"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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("RequestError: " + 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
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) DownloadAsset(info *AssetLocationInfo) (io.Reader, error) {
|
|
||||||
req, err := http.NewRequest("GET", info.Location, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, GetError("RequestCreationError: " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.HttpClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, GetError("RequestError: " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, GetError(fmt.Sprintf("ResponseError: status code %d", resp.StatusCode))
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Body, nil
|
|
||||||
}
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/users"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (svc *Service) ListAuditEvents(ctx context.Context, resource model.Resource, page model.Page) ([]api.AuditEvent, error){
|
|
||||||
filter := datastore.Optional()
|
|
||||||
|
|
||||||
filter.Add("resource_type", resource.Type)
|
|
||||||
filter.Add("resource_id", resource.ID)
|
|
||||||
|
|
||||||
items, err := svc.db.AuditEvents().List(ctx, filter, page)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
idMap := make(map[int64]bool)
|
|
||||||
for _, item := range items {
|
|
||||||
idMap[int64(item.User)] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var idList users.IdList
|
|
||||||
idList.ID = make([]int64,len(idMap))
|
|
||||||
for userId := range idMap {
|
|
||||||
idList.ID = append(idList.ID, userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
userList, err := svc.users.GetList(ctx, &idList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userMap := make(map[int64]*users.UserResponse)
|
|
||||||
for _,user := range userList.Users {
|
|
||||||
userMap[user.ID] = user
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp []api.AuditEvent
|
|
||||||
for _, item := range items {
|
|
||||||
EventData := api.AuditEventEventData{}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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) 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,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) CreateAuditEventChangeModel(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataChangeModel) 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.AuditEventTypeChangeModel,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) CreateAuditEventChangeDisplayName(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataChangeName) 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.AuditEventTypeChangeDisplayName,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) CreateAuditEventChangeCreator(ctx context.Context, userId uint64, resource model.Resource, event_data model.AuditEventDataChangeName) 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.AuditEventTypeChangeCreator,
|
|
||||||
EventData: EventData,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -2,115 +2,605 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MapfixUpdate datastore.OptionalMap
|
var(
|
||||||
|
CreationPhaseMapfixesLimit = 20
|
||||||
|
CreationPhaseMapfixStatuses = []model.MapfixStatus{
|
||||||
|
model.MapfixStatusChangesRequested,
|
||||||
|
model.MapfixStatusSubmitted,
|
||||||
|
model.MapfixStatusUnderConstruction,
|
||||||
|
}
|
||||||
|
// limit mapfixes in the pipeline to one per target map
|
||||||
|
ActiveAcceptedMapfixStatuses = []model.MapfixStatus{
|
||||||
|
model.MapfixStatusUploading,
|
||||||
|
model.MapfixStatusValidated,
|
||||||
|
model.MapfixStatusValidating,
|
||||||
|
model.MapfixStatusAccepted,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func NewMapfixUpdate() MapfixUpdate {
|
var (
|
||||||
update := datastore.Optional()
|
ErrCreationPhaseMapfixesLimit = errors.New("Active mapfixes limited to 20")
|
||||||
return MapfixUpdate(update)
|
ErrActiveMapfixSameTargetAssetID = errors.New("There is an active mapfix with the same TargetAssetID")
|
||||||
|
ErrAcceptOwnMapfix = fmt.Errorf("%w: You cannot accept your own mapfix as the submitter", ErrPermissionDenied)
|
||||||
|
)
|
||||||
|
|
||||||
|
// POST /mapfixes
|
||||||
|
func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixTriggerCreate) (*api.OperationID, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
userId, err := userInfo.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user's mapfixes in the creation phase exceeds the limit
|
||||||
|
{
|
||||||
|
filter := datastore.Optional()
|
||||||
|
filter.Add("submitter", int64(userId))
|
||||||
|
filter.Add("status_id", CreationPhaseMapfixStatuses)
|
||||||
|
creation_mapfixes, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
|
||||||
|
Number: 1,
|
||||||
|
Size: int32(CreationPhaseMapfixesLimit),
|
||||||
|
},datastore.ListSortDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if CreationPhaseMapfixesLimit <= len(creation_mapfixes) {
|
||||||
|
return nil, ErrCreationPhaseMapfixesLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if TargetAssetID actually exists
|
||||||
|
{
|
||||||
|
_, err := svc.Client.Get(ctx, &maps.IdMessage{
|
||||||
|
ID: request.TargetAssetID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// TODO: match specific does not exist grpc error
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operation, err := svc.DB.Operations().Create(ctx, model.Operation{
|
||||||
|
Owner: int64(userId),
|
||||||
|
StatusID: model.OperationStatusCreated,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
create_request := model.CreateMapfixRequest{
|
||||||
|
OperationID: operation.ID,
|
||||||
|
ModelID: request.AssetID,
|
||||||
|
TargetAssetID: request.TargetAssetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(create_request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.mapfixes.create", []byte(j))
|
||||||
|
|
||||||
|
return &api.OperationID{
|
||||||
|
OperationID: operation.ID,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (update MapfixUpdate) SetDisplayName(display_name string) {
|
// GetMapfix implements getMapfix operation.
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
//
|
||||||
}
|
// Retrieve map with ID.
|
||||||
func (update MapfixUpdate) SetCreator(creator string) {
|
//
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
// GET /mapfixes/{MapfixID}
|
||||||
}
|
func (svc *Service) GetMapfix(ctx context.Context, params api.GetMapfixParams) (*api.Mapfix, error) {
|
||||||
func (update MapfixUpdate) SetGameID(game_id uint32) {
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
func (update MapfixUpdate) SetSubmitter(submitter uint64) {
|
}
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
return &api.Mapfix{
|
||||||
}
|
ID: mapfix.ID,
|
||||||
func (update MapfixUpdate) SetAssetID(asset_id uint64) {
|
DisplayName: mapfix.DisplayName,
|
||||||
datastore.OptionalMap(update).Add("asset_id", asset_id)
|
Creator: mapfix.Creator,
|
||||||
}
|
GameID: mapfix.GameID,
|
||||||
func (update MapfixUpdate) SetAssetVersion(asset_version uint64) {
|
CreatedAt: mapfix.CreatedAt.Unix(),
|
||||||
datastore.OptionalMap(update).Add("asset_version", asset_version)
|
UpdatedAt: mapfix.UpdatedAt.Unix(),
|
||||||
}
|
Submitter: int64(mapfix.Submitter),
|
||||||
func (update MapfixUpdate) SetValidatedAssetID(validated_asset_id uint64) {
|
AssetID: int64(mapfix.AssetID),
|
||||||
datastore.OptionalMap(update).Add("validated_asset_id", validated_asset_id)
|
AssetVersion: int64(mapfix.AssetVersion),
|
||||||
}
|
Completed: mapfix.Completed,
|
||||||
func (update MapfixUpdate) SetValidatedAssetVersion(validated_asset_version uint64) {
|
TargetAssetID: int64(mapfix.TargetAssetID),
|
||||||
datastore.OptionalMap(update).Add("validated_asset_version", validated_asset_version)
|
StatusID: int32(mapfix.StatusID),
|
||||||
}
|
StatusMessage: mapfix.StatusMessage,
|
||||||
func (update MapfixUpdate) SetCompleted(completed bool) {
|
}, nil
|
||||||
datastore.OptionalMap(update).Add("completed", completed)
|
|
||||||
}
|
|
||||||
func (update MapfixUpdate) SetTargetAssetID(target_asset_id uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("target_asset_id", target_asset_id)
|
|
||||||
}
|
|
||||||
func (update MapfixUpdate) SetStatusID(status_id model.MapfixStatus) {
|
|
||||||
datastore.OptionalMap(update).Add("status_id", status_id)
|
|
||||||
}
|
|
||||||
func (update MapfixUpdate) SetDescription(description string) {
|
|
||||||
datastore.OptionalMap(update).Add("description", description)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MapfixFilter datastore.OptionalMap
|
// ListMapfixes implements listMapfixes operation.
|
||||||
|
//
|
||||||
func NewMapfixFilter(
|
// Get list of mapfixes.
|
||||||
) MapfixFilter {
|
//
|
||||||
|
// GET /mapfixes
|
||||||
|
func (svc *Service) ListMapfixes(ctx context.Context, params api.ListMapfixesParams) ([]api.Mapfix, error) {
|
||||||
filter := datastore.Optional()
|
filter := datastore.Optional()
|
||||||
return MapfixFilter(filter)
|
|
||||||
}
|
if params.DisplayName.IsSet(){
|
||||||
func (update MapfixFilter) SetDisplayName(display_name string) {
|
filter.Add("display_name", params.DisplayName.Value)
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
}
|
||||||
}
|
if params.Creator.IsSet(){
|
||||||
func (update MapfixFilter) SetCreator(creator string) {
|
filter.Add("creator", params.Creator.Value)
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
}
|
||||||
}
|
if params.GameID.IsSet(){
|
||||||
func (update MapfixFilter) SetGameID(game_id uint32) {
|
filter.Add("game_id", params.GameID.Value)
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
}
|
||||||
}
|
|
||||||
func (update MapfixFilter) SetSubmitter(submitter uint64) {
|
sort := datastore.ListSort(params.Sort.Or(int32(datastore.ListSortDisabled)))
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
|
||||||
}
|
items, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
|
||||||
func (update MapfixFilter) SetAssetID(asset_id uint64) {
|
Number: params.Page,
|
||||||
datastore.OptionalMap(update).Add("asset_id", asset_id)
|
Size: params.Limit,
|
||||||
}
|
},sort)
|
||||||
func (update MapfixFilter) SetAssetVersion(asset_version uint64) {
|
if err != nil {
|
||||||
datastore.OptionalMap(update).Add("asset_version", asset_version)
|
return nil, err
|
||||||
}
|
}
|
||||||
func (update MapfixFilter) SetTargetAssetID(target_asset_id uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("target_asset_id", target_asset_id)
|
var resp []api.Mapfix
|
||||||
}
|
for _, item := range items {
|
||||||
func (update MapfixFilter) SetStatuses(statuses []model.MapfixStatus) {
|
resp = append(resp, api.Mapfix{
|
||||||
datastore.OptionalMap(update).Add("status_id", statuses)
|
ID: item.ID,
|
||||||
|
DisplayName: item.DisplayName,
|
||||||
|
Creator: item.Creator,
|
||||||
|
GameID: item.GameID,
|
||||||
|
CreatedAt: item.CreatedAt.Unix(),
|
||||||
|
UpdatedAt: item.UpdatedAt.Unix(),
|
||||||
|
Submitter: int64(item.Submitter),
|
||||||
|
AssetID: int64(item.AssetID),
|
||||||
|
AssetVersion: int64(item.AssetVersion),
|
||||||
|
Completed: item.Completed,
|
||||||
|
TargetAssetID: int64(item.TargetAssetID),
|
||||||
|
StatusID: int32(item.StatusID),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) CreateMapfix(ctx context.Context, script model.Mapfix) (model.Mapfix, error) {
|
// PatchMapfixCompleted implements patchMapfixCompleted operation.
|
||||||
return svc.db.Mapfixes().Create(ctx, script)
|
//
|
||||||
|
// Retrieve map with ID.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/completed
|
||||||
|
func (svc *Service) SetMapfixCompleted(ctx context.Context, params api.SetMapfixCompletedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMaptest()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has MaptestGame role (request must originate from a maptest roblox game)
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMaptest
|
||||||
|
}
|
||||||
|
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.Add("completed", true)
|
||||||
|
return svc.DB.Mapfixes().Update(ctx, params.MapfixID, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListMapfixes(ctx context.Context, filter MapfixFilter, page model.Page, sort datastore.ListSort) ([]model.Mapfix, error) {
|
// UpdateMapfixModel implements patchMapfixModel operation.
|
||||||
return svc.db.Mapfixes().List(ctx, datastore.OptionalMap(filter), page, sort)
|
//
|
||||||
|
// Update model following role restrictions.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/model
|
||||||
|
func (svc *Service) UpdateMapfixModel(ctx context.Context, params api.UpdateMapfixModelParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read mapfix (this could be done with a transaction WHERE clause)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(mapfix.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.AddNotNil("asset_id", params.ModelID)
|
||||||
|
pmap.AddNotNil("asset_version", params.VersionID)
|
||||||
|
//always reset completed when model changes
|
||||||
|
pmap.Add("completed", false)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusChangesRequested, model.MapfixStatusSubmitted, model.MapfixStatusUnderConstruction}, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListMapfixesWithTotal(ctx context.Context, filter MapfixFilter, page model.Page, sort datastore.ListSort) (int64, []model.Mapfix, error) {
|
// ActionMapfixReject invokes actionMapfixReject operation.
|
||||||
return svc.db.Mapfixes().ListWithTotal(ctx, datastore.OptionalMap(filter), page, sort)
|
//
|
||||||
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/reject
|
||||||
|
func (svc *Service) ActionMapfixReject(ctx context.Context, params api.ActionMapfixRejectParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusRejected)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) DeleteMapfix(ctx context.Context, id int64) error {
|
// ActionMapfixRequestChanges invokes actionMapfixRequestChanges operation.
|
||||||
return svc.db.Mapfixes().Delete(ctx, id)
|
//
|
||||||
|
// Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/request-changes
|
||||||
|
func (svc *Service) ActionMapfixRequestChanges(ctx context.Context, params api.ActionMapfixRequestChangesParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusChangesRequested)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidated, model.MapfixStatusAccepted, model.MapfixStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) GetMapfix(ctx context.Context, id int64) (model.Mapfix, error) {
|
// ActionMapfixRevoke invokes actionMapfixRevoke operation.
|
||||||
return svc.db.Mapfixes().Get(ctx, id)
|
//
|
||||||
|
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/revoke
|
||||||
|
func (svc *Service) ActionMapfixRevoke(ctx context.Context, params api.ActionMapfixRevokeParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read mapfix (this could be done with a transaction WHERE clause)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(mapfix.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusUnderConstruction)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusSubmitted, model.MapfixStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateMapfix(ctx context.Context, id int64, pmap MapfixUpdate) error {
|
// ActionMapfixSubmit invokes actionMapfixSubmit operation.
|
||||||
return svc.db.Mapfixes().Update(ctx, id, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/submit
|
||||||
|
func (svc *Service) ActionMapfixSubmit(ctx context.Context, params api.ActionMapfixSubmitParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read mapfix (this could be done with a transaction WHERE clause)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(mapfix.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusSubmitted)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusUnderConstruction, model.MapfixStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateMapfixIfStatus(ctx context.Context, id int64, statuses []model.MapfixStatus, pmap MapfixUpdate) error {
|
// ActionMapfixTriggerUpload invokes actionMapfixTriggerUpload operation.
|
||||||
return svc.db.Mapfixes().IfStatusThenUpdate(ctx, id, statuses, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-upload
|
||||||
|
func (svc *Service) ActionMapfixTriggerUpload(ctx context.Context, params api.ActionMapfixTriggerUploadParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixUpload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusUploading)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().IfStatusThenUpdateAndGet(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidated}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is a map fix
|
||||||
|
upload_fix_request := model.UploadMapfixRequest{
|
||||||
|
MapfixID: mapfix.ID,
|
||||||
|
ModelID: mapfix.ValidatedAssetID,
|
||||||
|
ModelVersion: mapfix.ValidatedAssetVersion,
|
||||||
|
TargetAssetID: mapfix.TargetAssetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(upload_fix_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.mapfixes.uploadfix", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateAndGetMapfixIfStatus(ctx context.Context, id int64, statuses []model.MapfixStatus, pmap MapfixUpdate) (model.Mapfix, error) {
|
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
||||||
return svc.db.Mapfixes().IfStatusThenUpdateAndGet(ctx, id, statuses, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role MapfixRelease changes status from Uploading -> Validated.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/reset-uploading
|
||||||
|
func (svc *Service) ActionMapfixValidated(ctx context.Context, params api.ActionMapfixValidatedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixUpload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when mapfix was updated
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(mapfix.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the mapfix was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusValidated)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusUploading}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixTriggerValidate invokes actionMapfixTriggerValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer triggers validation and changes status from Submitted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/trigger-validate
|
||||||
|
func (svc *Service) ActionMapfixTriggerValidate(ctx context.Context, params api.ActionMapfixTriggerValidateParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// read mapfix (this could be done with a transaction WHERE clause)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err = userInfo.IsSubmitter(uint64(mapfix.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is NOT the submitter
|
||||||
|
if has_role {
|
||||||
|
return ErrAcceptOwnMapfix
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if an active mapfix with the same target asset id exists
|
||||||
|
if mapfix.TargetAssetID != 0 {
|
||||||
|
filter := datastore.Optional()
|
||||||
|
filter.Add("target_asset_id", mapfix.TargetAssetID)
|
||||||
|
filter.Add("status_id", ActiveAcceptedMapfixStatuses)
|
||||||
|
active_mapfixes, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
|
||||||
|
Number: 1,
|
||||||
|
Size: 1,
|
||||||
|
},datastore.ListSortDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(active_mapfixes) != 0{
|
||||||
|
return ErrActiveMapfixSameTargetAssetID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusValidating)
|
||||||
|
mapfix, err = svc.DB.Mapfixes().IfStatusThenUpdateAndGet(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusSubmitted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_request := model.ValidateMapfixRequest{
|
||||||
|
MapfixID: mapfix.ID,
|
||||||
|
ModelID: mapfix.AssetID,
|
||||||
|
ModelVersion: mapfix.AssetVersion,
|
||||||
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if mapfix.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &mapfix.ValidatedAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.mapfixes.validate", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixRetryValidate invokes actionMapfixRetryValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/retry-validate
|
||||||
|
func (svc *Service) ActionMapfixRetryValidate(ctx context.Context, params api.ActionMapfixRetryValidateParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusValidating)
|
||||||
|
mapfix, err := svc.DB.Mapfixes().IfStatusThenUpdateAndGet(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusAccepted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_request := model.ValidateMapfixRequest{
|
||||||
|
MapfixID: mapfix.ID,
|
||||||
|
ModelID: mapfix.AssetID,
|
||||||
|
ModelVersion: mapfix.AssetVersion,
|
||||||
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if mapfix.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &mapfix.ValidatedAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.mapfixes.validate", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
||||||
|
//
|
||||||
|
// Role MapfixReview changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/reset-validating
|
||||||
|
func (svc *Service) ActionMapfixAccepted(ctx context.Context, params api.ActionMapfixAcceptedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMapfixReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when mapfix was updated
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Get(ctx, params.MapfixID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(mapfix.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the mapfix was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusAccepted)
|
||||||
|
smap.Add("status_message", "Manually forced reset")
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, smap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,187 +2,72 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Optional map used to update an object
|
// ListMaps implements listMaps operation.
|
||||||
type MapUpdate datastore.OptionalMap
|
//
|
||||||
|
// Get list of maps.
|
||||||
|
//
|
||||||
|
// GET /maps
|
||||||
|
func (svc *Service) ListMaps(ctx context.Context, params api.ListMapsParams) ([]api.Map, error) {
|
||||||
|
filter := maps.MapFilter{}
|
||||||
|
|
||||||
func NewMapUpdate() MapUpdate {
|
if params.DisplayName.IsSet(){
|
||||||
update := datastore.Optional()
|
filter.DisplayName = ¶ms.DisplayName.Value
|
||||||
return MapUpdate(update)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (update MapUpdate) SetDisplayName(display_name string) {
|
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetCreator(creator string) {
|
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetGameID(game_id uint32) {
|
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetDate(date int64) {
|
|
||||||
datastore.OptionalMap(update).Add("date", date)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetSubmitter(submitter uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetThumbnail(thumbnail uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("thumbnail", thumbnail)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetAssetVersion(asset_version uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("asset_version", asset_version)
|
|
||||||
}
|
|
||||||
func (update MapUpdate) SetModes(modes uint32) {
|
|
||||||
datastore.OptionalMap(update).Add("modes", modes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
func (update MapUpdate) GetDisplayName() (string, bool) {
|
|
||||||
value, ok := datastore.OptionalMap(update).Map()["display_name"].(string)
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
func (update MapUpdate) GetCreator() (string, bool) {
|
|
||||||
value, ok := datastore.OptionalMap(update).Map()["creator"].(string)
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
func (update MapUpdate) GetGameID() (uint32, bool) {
|
|
||||||
value, ok := datastore.OptionalMap(update).Map()["game_id"].(uint32)
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
func (update MapUpdate) GetDate() (int64, bool) {
|
|
||||||
value, ok := datastore.OptionalMap(update).Map()["date"].(int64)
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optional map used to find matching objects
|
|
||||||
type MapFilter datastore.OptionalMap
|
|
||||||
|
|
||||||
func NewMapFilter(
|
|
||||||
) MapFilter {
|
|
||||||
filter := datastore.Optional()
|
|
||||||
return MapFilter(filter)
|
|
||||||
}
|
|
||||||
func (update MapFilter) SetDisplayName(display_name string) {
|
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
|
||||||
}
|
|
||||||
func (update MapFilter) SetCreator(creator string) {
|
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
|
||||||
}
|
|
||||||
func (update MapFilter) SetGameID(game_id uint32) {
|
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
|
||||||
}
|
|
||||||
func (update MapFilter) SetSubmitter(submitter uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) TEMP_DoMapsMigration(ctx context.Context) (error) {
|
|
||||||
// get all maps
|
|
||||||
maps, err := svc.maps.List(ctx, &maps.ListRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create all maps
|
if params.Creator.IsSet(){
|
||||||
for _, item := range maps.Maps {
|
filter.Creator = ¶ms.Creator.Value
|
||||||
migrated := model.Map{
|
}
|
||||||
|
if params.GameID.IsSet(){
|
||||||
|
filter.GameID = ¶ms.GameID.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
mapList, err := svc.Client.List(ctx, &maps.ListRequest{
|
||||||
|
Filter: &filter,
|
||||||
|
Page: &maps.Pagination{
|
||||||
|
Size: params.Limit,
|
||||||
|
Number: params.Page,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []api.Map
|
||||||
|
for _, item := range mapList.Maps {
|
||||||
|
resp = append(resp, api.Map{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
DisplayName: item.DisplayName,
|
DisplayName: item.DisplayName,
|
||||||
Creator: item.Creator,
|
Creator: item.Creator,
|
||||||
GameID: uint32(item.GameID),
|
GameID: item.GameID,
|
||||||
Date: time.Unix(item.Date, 0),
|
Date: item.Date,
|
||||||
// CreatedAt: time.Time{},
|
})
|
||||||
// UpdatedAt: time.Time{},
|
|
||||||
// Submitter: 0,
|
|
||||||
// Thumbnail: 0,
|
|
||||||
// AssetVersion: 0,
|
|
||||||
// LoadCount: 0,
|
|
||||||
// Modes: 0,
|
|
||||||
}
|
|
||||||
_, err := svc.db.Maps().Create(ctx, migrated)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
func (svc *Service) CreateMap(ctx context.Context, item model.Map) (int64, error) {
|
|
||||||
// 2 jobs:
|
// GetMap implements getScript operation.
|
||||||
// create map on maps-service
|
//
|
||||||
map_item, err := svc.db.Maps().Create(ctx, item)
|
// Get the specified script by ID.
|
||||||
if err != nil {
|
//
|
||||||
return 0, err
|
// GET /maps/{MapID}
|
||||||
}
|
func (svc *Service) GetMap(ctx context.Context, params api.GetMapParams) (*api.Map, error) {
|
||||||
// create map on data-service
|
mapResponse, err := svc.Client.Get(ctx, &maps.IdMessage{
|
||||||
date := item.Date.Unix()
|
ID: params.MapID,
|
||||||
game_id := int32(item.GameID)
|
|
||||||
_, err = svc.maps.Create(ctx, &maps.MapRequest{
|
|
||||||
ID: item.ID,
|
|
||||||
DisplayName: &item.DisplayName,
|
|
||||||
Creator: &item.Creator,
|
|
||||||
GameID: &game_id,
|
|
||||||
Date: &date,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return map_item.ID, nil
|
return &api.Map{
|
||||||
}
|
ID: mapResponse.ID,
|
||||||
|
DisplayName: mapResponse.DisplayName,
|
||||||
func (svc *Service) ListMaps(ctx context.Context, filter MapFilter, page model.Page) ([]model.Map, error) {
|
Creator: mapResponse.Creator,
|
||||||
return svc.db.Maps().List(ctx, datastore.OptionalMap(filter), page)
|
GameID: mapResponse.GameID,
|
||||||
}
|
Date: mapResponse.Date,
|
||||||
|
}, nil
|
||||||
func (svc *Service) GetMapList(ctx context.Context, ids []int64) ([]model.Map, error) {
|
|
||||||
return svc.db.Maps().GetList(ctx, ids)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) DeleteMap(ctx context.Context, id int64) error {
|
|
||||||
// Do not delete the "embedded" map, since it deletes times.
|
|
||||||
// _, err := svc.maps.Delete(ctx, &maps.IdMessage{ID: id})
|
|
||||||
return svc.db.Maps().Delete(ctx, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) GetMap(ctx context.Context, id int64) (model.Map, error) {
|
|
||||||
return svc.db.Maps().Get(ctx, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) UpdateMap(ctx context.Context, id int64, pmap MapUpdate) error {
|
|
||||||
// 2 jobs:
|
|
||||||
// update map on maps-service
|
|
||||||
err := svc.db.Maps().Update(ctx, id, datastore.OptionalMap(pmap))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// update map on data-service
|
|
||||||
update := maps.MapRequest{
|
|
||||||
ID: id,
|
|
||||||
}
|
|
||||||
if display_name, ok := pmap.GetDisplayName(); ok {
|
|
||||||
update.DisplayName = &display_name
|
|
||||||
}
|
|
||||||
if creator, ok := pmap.GetCreator(); ok {
|
|
||||||
update.Creator = &creator
|
|
||||||
}
|
|
||||||
if game_id, ok := pmap.GetGameID(); ok {
|
|
||||||
game_id_int32 := int32(game_id)
|
|
||||||
update.GameID = &game_id_int32
|
|
||||||
}
|
|
||||||
if date, ok := pmap.GetDate(); ok {
|
|
||||||
update.Date = &date
|
|
||||||
}
|
|
||||||
_, err = svc.maps.Update(ctx, &update)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) IncrementMapLoadCount(ctx context.Context, id int64) error {
|
|
||||||
return svc.db.Maps().IncrementLoadCount(ctx, id)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (svc *Service) NatsCreateMapfix(
|
|
||||||
OperationID int32,
|
|
||||||
ModelID uint64,
|
|
||||||
TargetAssetID uint64,
|
|
||||||
Description string,
|
|
||||||
) error {
|
|
||||||
create_request := model.CreateMapfixRequest{
|
|
||||||
OperationID: OperationID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
TargetAssetID: TargetAssetID,
|
|
||||||
Description: Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(create_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.mapfixes.create", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsCheckMapfix(
|
|
||||||
MapfixID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
SkipChecks bool,
|
|
||||||
) error {
|
|
||||||
validate_request := model.CheckMapfixRequest{
|
|
||||||
MapfixID: MapfixID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
SkipChecks: SkipChecks,
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsUploadMapfix(
|
|
||||||
MapfixID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
ModelVersion uint64,
|
|
||||||
TargetAssetID uint64,
|
|
||||||
) error {
|
|
||||||
upload_fix_request := model.UploadMapfixRequest{
|
|
||||||
MapfixID: MapfixID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
ModelVersion: ModelVersion,
|
|
||||||
TargetAssetID: TargetAssetID,
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(upload_fix_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.mapfixes.upload", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsValidateMapfix(
|
|
||||||
MapfixID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
ModelVersion uint64,
|
|
||||||
ValidatedAssetID uint64,
|
|
||||||
) error {
|
|
||||||
validate_request := model.ValidateMapfixRequest{
|
|
||||||
MapfixID: MapfixID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
ModelVersion: ModelVersion,
|
|
||||||
ValidatedModelID: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
// sentinel values because we're not using rust
|
|
||||||
if ValidatedAssetID != 0 {
|
|
||||||
validate_request.ValidatedModelID = &ValidatedAssetID
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(validate_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.mapfixes.validate", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (svc *Service) NatsCreateSubmission(
|
|
||||||
OperationID int32,
|
|
||||||
ModelID uint64,
|
|
||||||
DisplayName string,
|
|
||||||
Creator string,
|
|
||||||
GameID uint32,
|
|
||||||
Status uint32,
|
|
||||||
Roles uint32,
|
|
||||||
) error {
|
|
||||||
create_request := model.CreateSubmissionRequest{
|
|
||||||
OperationID: OperationID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
DisplayName: DisplayName,
|
|
||||||
Creator: Creator,
|
|
||||||
GameID: GameID,
|
|
||||||
Status: Status,
|
|
||||||
Roles: Roles,
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(create_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.submissions.create", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsCheckSubmission(
|
|
||||||
SubmissionID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
SkipChecks bool,
|
|
||||||
) error {
|
|
||||||
validate_request := model.CheckSubmissionRequest{
|
|
||||||
SubmissionID: SubmissionID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
SkipChecks: SkipChecks,
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsUploadSubmission(
|
|
||||||
SubmissionID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
ModelVersion uint64,
|
|
||||||
ModelName string,
|
|
||||||
) error {
|
|
||||||
upload_new_request := model.UploadSubmissionRequest{
|
|
||||||
SubmissionID: SubmissionID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
ModelVersion: ModelVersion,
|
|
||||||
ModelName: ModelName,
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(upload_new_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.submissions.upload", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) NatsValidateSubmission(
|
|
||||||
SubmissionID int64,
|
|
||||||
ModelID uint64,
|
|
||||||
ModelVersion uint64,
|
|
||||||
ValidatedModelID uint64,
|
|
||||||
) error {
|
|
||||||
validate_request := model.ValidateSubmissionRequest{
|
|
||||||
SubmissionID: SubmissionID,
|
|
||||||
ModelID: ModelID,
|
|
||||||
ModelVersion: ModelVersion,
|
|
||||||
ValidatedModelID: nil,
|
|
||||||
}
|
|
||||||
|
|
||||||
// sentinel values because we're not using rust
|
|
||||||
if ValidatedModelID != 0 {
|
|
||||||
validate_request.ValidatedModelID = &ValidatedModelID
|
|
||||||
}
|
|
||||||
|
|
||||||
j, err := json.Marshal(validate_request)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svc.nats.Publish("maptest.submissions.validate", []byte(j))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -2,54 +2,43 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperationFailParams datastore.OptionalMap
|
// GetOperation implements getOperation operation.
|
||||||
|
//
|
||||||
|
// Get the specified operation by ID.
|
||||||
|
//
|
||||||
|
// GET /operations/{OperationID}
|
||||||
|
func (svc *Service) GetOperation(ctx context.Context, params api.GetOperationParams) (*api.Operation, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
func NewOperationFailParams(
|
// You must be the operation owner to read it
|
||||||
status_message string,
|
|
||||||
) OperationFailParams {
|
operation, err := svc.DB.Operations().Get(ctx, params.OperationID)
|
||||||
filter := datastore.Optional()
|
if err != nil {
|
||||||
filter.Add("status_id", model.OperationStatusFailed)
|
return nil, err
|
||||||
filter.Add("status_message", status_message)
|
}
|
||||||
return OperationFailParams(filter)
|
|
||||||
}
|
has_role, err := userInfo.IsSubmitter(uint64(operation.Owner))
|
||||||
|
if err != nil {
|
||||||
type OperationCompleteParams datastore.OptionalMap
|
return nil, err
|
||||||
|
}
|
||||||
func NewOperationCompleteParams(
|
// check if caller is operation owner
|
||||||
path string,
|
if !has_role {
|
||||||
) OperationCompleteParams {
|
return nil, ErrPermissionDeniedNotSubmitter
|
||||||
filter := datastore.Optional()
|
}
|
||||||
filter.Add("status_id", model.OperationStatusCompleted)
|
|
||||||
filter.Add("path", path)
|
return &api.Operation{
|
||||||
return OperationCompleteParams(filter)
|
OperationID: operation.ID,
|
||||||
}
|
Date: operation.CreatedAt.Unix(),
|
||||||
|
Owner: operation.Owner,
|
||||||
func (svc *Service) CreateOperation(ctx context.Context, operation model.Operation) (model.Operation, error) {
|
Status: int32(operation.StatusID),
|
||||||
return svc.db.Operations().Create(ctx, operation)
|
StatusMessage: operation.StatusMessage,
|
||||||
}
|
Path: operation.Path,
|
||||||
|
}, nil
|
||||||
func (svc *Service) CountOperationsSince(ctx context.Context, owner int64, since time.Time) (int64, error) {
|
|
||||||
return svc.db.Operations().CountSince(ctx, owner, since)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) DeleteOperation(ctx context.Context, id int32) error {
|
|
||||||
return svc.db.Operations().Delete(ctx, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) GetOperation(ctx context.Context, id int32) (model.Operation, error) {
|
|
||||||
return svc.db.Operations().Get(ctx, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) FailOperation(ctx context.Context, id int32, params OperationFailParams) error {
|
|
||||||
return svc.db.Operations().Update(ctx, id, datastore.OptionalMap(params))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svc *Service) CompleteOperation(ctx context.Context, id int32, params OperationCompleteParams) error {
|
|
||||||
return svc.db.Operations().Update(ctx, id, datastore.OptionalMap(params))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,43 +3,176 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScriptPolicyFilter datastore.OptionalMap
|
// CreateScriptPolicy implements createScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Create a new script policy.
|
||||||
|
//
|
||||||
|
// POST /script-policy
|
||||||
|
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ScriptPolicyID, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
func NewScriptPolicyFilter() ScriptPolicyFilter {
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return nil, ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
from_script, err := svc.DB.Scripts().Get(ctx, req.FromScriptID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
|
||||||
|
|
||||||
|
script, err := svc.DB.ScriptPolicy().Create(ctx, model.ScriptPolicy{
|
||||||
|
ID: 0,
|
||||||
|
FromScriptHash: from_script.Hash,
|
||||||
|
ToScriptID: req.ToScriptID,
|
||||||
|
Policy: model.Policy(req.Policy),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ScriptPolicyID{
|
||||||
|
ScriptPolicyID: script.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ListScriptPolicy implements listScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Get list of script policies.
|
||||||
|
//
|
||||||
|
// GET /script-policy
|
||||||
|
func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptPolicyParams) ([]api.ScriptPolicy, error) {
|
||||||
filter := datastore.Optional()
|
filter := datastore.Optional()
|
||||||
return ScriptPolicyFilter(filter)
|
|
||||||
}
|
if params.FromScriptHash.IsSet(){
|
||||||
func (filter ScriptPolicyFilter) SetFromScriptHash(from_script_hash int64) {
|
hash, err := model.HashParse(params.FromScriptHash.Value)
|
||||||
// Finally, type safety!
|
if err != nil {
|
||||||
datastore.OptionalMap(filter).Add("from_script_hash", from_script_hash)
|
return nil, err
|
||||||
}
|
}
|
||||||
func (filter ScriptPolicyFilter) SetToScriptID(to_script_id int64) {
|
filter.AddNotNil("from_script_hash", int64(hash)) // No type safety!
|
||||||
datastore.OptionalMap(filter).Add("to_script_id", to_script_id)
|
}
|
||||||
}
|
if params.ToScriptID.IsSet(){
|
||||||
func (filter ScriptPolicyFilter) SetPolicy(policy int32) {
|
filter.AddNotNil("to_script_id", params.ToScriptID.Value)
|
||||||
datastore.OptionalMap(filter).Add("policy", policy)
|
}
|
||||||
|
if params.Policy.IsSet(){
|
||||||
|
filter.AddNotNil("policy", params.Policy.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := svc.DB.ScriptPolicy().List(ctx, filter, model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []api.ScriptPolicy
|
||||||
|
for _, item := range items {
|
||||||
|
resp = append(resp, api.ScriptPolicy{
|
||||||
|
ID: item.ID,
|
||||||
|
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
|
||||||
|
ToScriptID: item.ToScriptID,
|
||||||
|
Policy: int32(item.Policy),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) CreateScriptPolicy(ctx context.Context, script model.ScriptPolicy) (model.ScriptPolicy, error) {
|
// DeleteScriptPolicy implements deleteScriptPolicy operation.
|
||||||
return svc.db.ScriptPolicy().Create(ctx, script)
|
//
|
||||||
|
// Delete the specified script policy by ID.
|
||||||
|
//
|
||||||
|
// DELETE /script-policy/{ScriptPolicyID}
|
||||||
|
func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScriptPolicyParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.DB.ScriptPolicy().Delete(ctx, params.ScriptPolicyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListScriptPolicies(ctx context.Context, filter ScriptPolicyFilter, page model.Page) ([]model.ScriptPolicy, error) {
|
// GetScriptPolicy implements getScriptPolicy operation.
|
||||||
return svc.db.ScriptPolicy().List(ctx, datastore.OptionalMap(filter), page)
|
//
|
||||||
|
// Get the specified script policy by ID.
|
||||||
|
//
|
||||||
|
// GET /script-policy/{ScriptPolicyID}
|
||||||
|
func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPolicyParams) (*api.ScriptPolicy, error) {
|
||||||
|
_, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read permission for script policy only requires you to be logged in
|
||||||
|
|
||||||
|
policy, err := svc.DB.ScriptPolicy().Get(ctx, params.ScriptPolicyID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ScriptPolicy{
|
||||||
|
ID: policy.ID,
|
||||||
|
FromScriptHash: model.HashFormat(uint64(policy.FromScriptHash)),
|
||||||
|
ToScriptID: policy.ToScriptID,
|
||||||
|
Policy: int32(policy.Policy),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) DeleteScriptPolicy(ctx context.Context, id int64) error {
|
// UpdateScriptPolicy implements updateScriptPolicy operation.
|
||||||
return svc.db.ScriptPolicy().Delete(ctx, id)
|
//
|
||||||
}
|
// Update the specified script policy by ID.
|
||||||
|
//
|
||||||
|
// POST /script-policy/{ScriptPolicyID}
|
||||||
|
func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolicyUpdate, params api.UpdateScriptPolicyParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *Service) GetScriptPolicy(ctx context.Context, id int64) (model.ScriptPolicy, error) {
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
return svc.db.ScriptPolicy().Get(ctx, id)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateScriptPolicy(ctx context.Context, id int64, pmap ScriptPolicyFilter) error {
|
pmap := datastore.Optional()
|
||||||
return svc.db.ScriptPolicy().Update(ctx, id, datastore.OptionalMap(pmap))
|
if from_script_id, ok := req.FromScriptID.Get(); ok {
|
||||||
|
from_script, err := svc.DB.Scripts().Get(ctx, from_script_id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pmap.Add("from_script_hash", from_script.Hash)
|
||||||
|
}
|
||||||
|
if to_script_id, ok := req.ToScriptID.Get(); ok {
|
||||||
|
pmap.Add("to_script_id", to_script_id)
|
||||||
|
}
|
||||||
|
if policy, ok := req.Policy.Get(); ok {
|
||||||
|
pmap.Add("policy", policy)
|
||||||
|
}
|
||||||
|
return svc.DB.ScriptPolicy().Update(ctx, req.ID, pmap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,48 +3,179 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScriptFilter datastore.OptionalMap
|
// CreateScript implements createScript operation.
|
||||||
|
//
|
||||||
|
// Create a new script.
|
||||||
|
//
|
||||||
|
// POST /scripts
|
||||||
|
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ScriptID, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
func NewScriptFilter() ScriptFilter {
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return nil, ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
script, err := svc.DB.Scripts().Create(ctx, model.Script{
|
||||||
|
ID: 0,
|
||||||
|
Name: req.Name,
|
||||||
|
Hash: int64(model.HashSource(req.Source)),
|
||||||
|
Source: req.Source,
|
||||||
|
ResourceType: model.ResourceType(req.ResourceType),
|
||||||
|
ResourceID: req.ResourceID.Or(0),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ScriptID{
|
||||||
|
ScriptID: script.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListScripts implements listScripts operation.
|
||||||
|
//
|
||||||
|
// Get list of scripts.
|
||||||
|
//
|
||||||
|
// GET /scripts
|
||||||
|
func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParams) ([]api.Script, error) {
|
||||||
filter := datastore.Optional()
|
filter := datastore.Optional()
|
||||||
return ScriptFilter(filter)
|
|
||||||
}
|
if params.Hash.IsSet(){
|
||||||
func (filter ScriptFilter) SetName(name string) {
|
hash, err := model.HashParse(params.Hash.Value)
|
||||||
datastore.OptionalMap(filter).Add("name", name)
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
func (filter ScriptFilter) SetSource(source string) {
|
}
|
||||||
datastore.OptionalMap(filter).Add("source", source)
|
filter.AddNotNil("hash", int64(hash)) // No type safety!
|
||||||
}
|
}
|
||||||
func (filter ScriptFilter) SetHash(hash int64) {
|
if params.Name.IsSet(){
|
||||||
datastore.OptionalMap(filter).Add("hash", hash)
|
filter.AddNotNil("name", params.Name.Value)
|
||||||
}
|
}
|
||||||
func (filter ScriptFilter) SetResourceType(resource_type int32) {
|
if params.Source.IsSet(){
|
||||||
datastore.OptionalMap(filter).Add("resource_type", resource_type)
|
filter.AddNotNil("source", params.Source.Value)
|
||||||
}
|
}
|
||||||
func (filter ScriptFilter) SetResourceID(resource_id int64) {
|
if params.ResourceType.IsSet(){
|
||||||
datastore.OptionalMap(filter).Add("resource_id", resource_id)
|
filter.AddNotNil("resource_type", params.ResourceType.Value)
|
||||||
|
}
|
||||||
|
if params.ResourceID.IsSet(){
|
||||||
|
filter.AddNotNil("resource_id", params.ResourceID.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := svc.DB.Scripts().List(ctx, filter, model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []api.Script
|
||||||
|
for _, item := range items {
|
||||||
|
resp = append(resp, api.Script{
|
||||||
|
ID: item.ID,
|
||||||
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
|
Source: item.Source,
|
||||||
|
ResourceType: int32(item.ResourceType),
|
||||||
|
ResourceID: item.ResourceID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) CreateScript(ctx context.Context, script model.Script) (model.Script, error) {
|
// DeleteScript implements deleteScript operation.
|
||||||
return svc.db.Scripts().Create(ctx, script)
|
//
|
||||||
|
// Delete the specified script by ID.
|
||||||
|
//
|
||||||
|
// DELETE /scripts/{ScriptID}
|
||||||
|
func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc.DB.Scripts().Delete(ctx, params.ScriptID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListScripts(ctx context.Context, filter ScriptFilter, page model.Page) ([]model.Script, error) {
|
// GetScript implements getScript operation.
|
||||||
return svc.db.Scripts().List(ctx, datastore.OptionalMap(filter), page)
|
//
|
||||||
|
// Get the specified script by ID.
|
||||||
|
//
|
||||||
|
// GET /scripts/{ScriptID}
|
||||||
|
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
|
||||||
|
_, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read permission for scripts only requires you to be logged in
|
||||||
|
|
||||||
|
script, err := svc.DB.Scripts().Get(ctx, params.ScriptID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.Script{
|
||||||
|
ID: script.ID,
|
||||||
|
Name: script.Name,
|
||||||
|
Hash: model.HashFormat(uint64(script.Hash)),
|
||||||
|
Source: script.Source,
|
||||||
|
ResourceType: int32(script.ResourceType),
|
||||||
|
ResourceID: script.ResourceID,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) DeleteScript(ctx context.Context, id int64) error {
|
// UpdateScript implements updateScript operation.
|
||||||
return svc.db.Scripts().Delete(ctx, id)
|
//
|
||||||
}
|
// Update the specified script by ID.
|
||||||
|
//
|
||||||
|
// PATCH /scripts/{ScriptID}
|
||||||
|
func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, params api.UpdateScriptParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *Service) GetScript(ctx context.Context, id int64) (model.Script, error) {
|
has_role, err := userInfo.HasRoleScriptWrite()
|
||||||
return svc.db.Scripts().Get(ctx, id)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateScript(ctx context.Context, id int64, pmap ScriptFilter) error {
|
pmap := datastore.Optional()
|
||||||
return svc.db.Scripts().Update(ctx, id, datastore.OptionalMap(pmap))
|
if Name, ok := req.Name.Get(); ok {
|
||||||
|
pmap.Add("name", Name)
|
||||||
|
}
|
||||||
|
if source, ok := req.Source.Get(); ok {
|
||||||
|
pmap.Add("source", source)
|
||||||
|
pmap.Add("hash", int64(model.HashSource(source))) // No type safety!
|
||||||
|
}
|
||||||
|
if ResourceType, ok := req.ResourceType.Get(); ok {
|
||||||
|
pmap.Add("resource_type", ResourceType)
|
||||||
|
}
|
||||||
|
if ResourceID, ok := req.ResourceID.Get(); ok {
|
||||||
|
pmap.Add("resource_id", ResourceID)
|
||||||
|
}
|
||||||
|
return svc.DB.Scripts().Update(ctx, req.ID, pmap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package web_api
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/auth"
|
"git.itzana.me/strafesnet/go-grpc/auth"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -16,6 +14,38 @@ var (
|
|||||||
ErrInvalidSession = errors.New("Session invalid")
|
ErrInvalidSession = errors.New("Session invalid")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Submissions roles bitflag
|
||||||
|
type Roles int32
|
||||||
|
var (
|
||||||
|
RolesSubmissionUpload Roles = 1<<6
|
||||||
|
RolesSubmissionReview Roles = 1<<5
|
||||||
|
RolesSubmissionRelease Roles = 1<<4
|
||||||
|
RolesScriptWrite Roles = 1<<3
|
||||||
|
RolesMapfixUpload Roles = 1<<2
|
||||||
|
RolesMapfixReview Roles = 1<<1
|
||||||
|
RolesMapDownload Roles = 1<<0
|
||||||
|
RolesEmpty Roles = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// StrafesNET group roles
|
||||||
|
type GroupRole int32
|
||||||
|
var (
|
||||||
|
// has ScriptWrite
|
||||||
|
RoleQuat GroupRole = 255
|
||||||
|
RoleItzaname GroupRole = 254
|
||||||
|
RoleStagingDeveloper GroupRole = 240
|
||||||
|
RolesAll Roles = ^RolesEmpty
|
||||||
|
// has SubmissionUpload
|
||||||
|
RoleMapAdmin GroupRole = 128
|
||||||
|
RolesMapAdmin Roles = RolesSubmissionRelease|RolesSubmissionUpload|RolesSubmissionReview|RolesMapCouncil
|
||||||
|
// has MapfixReview
|
||||||
|
RoleMapCouncil GroupRole = 64
|
||||||
|
RolesMapCouncil Roles = RolesMapfixReview|RolesMapfixUpload|RolesMapAccess
|
||||||
|
// access to downloading maps
|
||||||
|
RoleMapAccess GroupRole = 32
|
||||||
|
RolesMapAccess Roles = RolesMapDownload
|
||||||
|
)
|
||||||
|
|
||||||
type UserInfoHandle struct {
|
type UserInfoHandle struct {
|
||||||
// Would love to know a better way to do this
|
// Would love to know a better way to do this
|
||||||
svc *SecurityHandler
|
svc *SecurityHandler
|
||||||
@@ -58,7 +88,14 @@ func (usr UserInfoHandle) Validate() (bool, error) {
|
|||||||
}
|
}
|
||||||
return validate.Valid, nil
|
return validate.Valid, nil
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) hasRoles(wantRoles model.Roles) (bool, error) {
|
func (usr UserInfoHandle) IsSubmitter(submitter uint64) (bool, error) {
|
||||||
|
userId, err := usr.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return userId == submitter, nil
|
||||||
|
}
|
||||||
|
func (usr UserInfoHandle) hasRoles(wantRoles Roles) (bool, error) {
|
||||||
haveroles, err := usr.GetRoles()
|
haveroles, err := usr.GetRoles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -66,27 +103,27 @@ func (usr UserInfoHandle) hasRoles(wantRoles model.Roles) (bool, error) {
|
|||||||
|
|
||||||
return haveroles & wantRoles == wantRoles, nil
|
return haveroles & wantRoles == wantRoles, nil
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) GetRoles() (model.Roles, error) {
|
func (usr UserInfoHandle) GetRoles() (Roles, error) {
|
||||||
roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{
|
roles, err := usr.svc.Client.GetGroupRole(*usr.ctx, &auth.IdMessage{
|
||||||
SessionID: usr.sessionId,
|
SessionID: usr.sessionId,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.RolesEmpty, err
|
return RolesEmpty, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// map roles into bitflag
|
// map roles into bitflag
|
||||||
rolesBitflag := model.RolesEmpty;
|
rolesBitflag := RolesEmpty;
|
||||||
for _, r := range roles.Roles {
|
for _, r := range roles.Roles {
|
||||||
switch model.GroupRole(r.Rank){
|
switch GroupRole(r.Rank){
|
||||||
case model.RoleQuat, model.RoleItzaname, model.RoleStagingDeveloper:
|
case RoleQuat, RoleItzaname, RoleStagingDeveloper:
|
||||||
rolesBitflag|=model.RolesAll
|
rolesBitflag|=RolesAll
|
||||||
case model.RoleMapAdmin:
|
case RoleMapAdmin:
|
||||||
rolesBitflag|=model.RolesMapAdmin
|
rolesBitflag|=RolesMapAdmin
|
||||||
case model.RoleMapCouncil:
|
case RoleMapCouncil:
|
||||||
rolesBitflag|=model.RolesMapCouncil
|
rolesBitflag|=RolesMapCouncil
|
||||||
case model.RoleMapAccess:
|
case RoleMapAccess:
|
||||||
rolesBitflag|=model.RolesMapAccess
|
rolesBitflag|=RolesMapAccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rolesBitflag, nil
|
return rolesBitflag, nil
|
||||||
@@ -94,25 +131,25 @@ func (usr UserInfoHandle) GetRoles() (model.Roles, error) {
|
|||||||
|
|
||||||
// RoleThumbnail
|
// RoleThumbnail
|
||||||
func (usr UserInfoHandle) HasRoleMapfixUpload() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMapfixUpload() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesMapfixUpload)
|
return usr.hasRoles(RolesMapfixUpload)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleMapfixReview() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMapfixReview() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesMapfixReview)
|
return usr.hasRoles(RolesMapfixReview)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMapDownload() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesMapDownload)
|
return usr.hasRoles(RolesMapDownload)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleSubmissionRelease() (bool, error) {
|
func (usr UserInfoHandle) HasRoleSubmissionRelease() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesSubmissionRelease)
|
return usr.hasRoles(RolesSubmissionRelease)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleSubmissionUpload() (bool, error) {
|
func (usr UserInfoHandle) HasRoleSubmissionUpload() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesSubmissionUpload)
|
return usr.hasRoles(RolesSubmissionUpload)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleSubmissionReview() (bool, error) {
|
func (usr UserInfoHandle) HasRoleSubmissionReview() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesSubmissionReview)
|
return usr.hasRoles(RolesSubmissionReview)
|
||||||
}
|
}
|
||||||
func (usr UserInfoHandle) HasRoleScriptWrite() (bool, error) {
|
func (usr UserInfoHandle) HasRoleScriptWrite() (bool, error) {
|
||||||
return usr.hasRoles(model.RolesScriptWrite)
|
return usr.hasRoles(RolesScriptWrite)
|
||||||
}
|
}
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
func (usr UserInfoHandle) HasRoleMaptest() (bool, error) {
|
func (usr UserInfoHandle) HasRoleMaptest() (bool, error) {
|
||||||
@@ -1,29 +1,56 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/maps"
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
"git.itzana.me/strafesnet/go-grpc/users"
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrPermissionDenied caller does not have the required role
|
||||||
|
ErrPermissionDenied = errors.New("Permission denied")
|
||||||
|
// ErrUserInfo user info is missing for some reason
|
||||||
|
ErrUserInfo = errors.New("Missing user info")
|
||||||
|
ErrDelayReset = errors.New("Please give the validator at least 10 seconds to operate before attempting to reset the status")
|
||||||
|
ErrPermissionDeniedNotSubmitter = fmt.Errorf("%w: You must be the submitter to perform this action", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleSubmissionRelease = fmt.Errorf("%w: Need Role SubmissionRelease", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapUpload = fmt.Errorf("%w: Need Role MapUpload", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapReview = fmt.Errorf("%w: Need Role MapReview", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMapDownload = fmt.Errorf("%w: Need Role MapDownload", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleScriptWrite = fmt.Errorf("%w: Need Role ScriptWrite", ErrPermissionDenied)
|
||||||
|
ErrPermissionDeniedNeedRoleMaptest = fmt.Errorf("%w: Need Role Maptest", ErrPermissionDenied)
|
||||||
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
db datastore.Datastore
|
DB datastore.Datastore
|
||||||
nats nats.JetStreamContext
|
Nats nats.JetStreamContext
|
||||||
maps maps.MapsServiceClient
|
Client maps.MapsServiceClient
|
||||||
users users.UsersServiceClient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(
|
// NewError creates *ErrorStatusCode from error returned by handler.
|
||||||
db datastore.Datastore,
|
//
|
||||||
nats nats.JetStreamContext,
|
// Used for common default response.
|
||||||
maps maps.MapsServiceClient,
|
func (svc *Service) NewError(ctx context.Context, err error) *api.ErrorStatusCode {
|
||||||
users users.UsersServiceClient,
|
status := 500
|
||||||
) Service {
|
if errors.Is(err, datastore.ErrNotExist) {
|
||||||
return Service{
|
status = 404
|
||||||
db: db,
|
}
|
||||||
nats: nats,
|
if errors.Is(err, ErrPermissionDenied) {
|
||||||
maps: maps,
|
status = 403
|
||||||
users: users,
|
}
|
||||||
|
if errors.Is(err, ErrUserInfo) {
|
||||||
|
status = 401
|
||||||
|
}
|
||||||
|
return &api.ErrorStatusCode{
|
||||||
|
StatusCode: status,
|
||||||
|
Response: api.Error{
|
||||||
|
Code: int64(status),
|
||||||
|
Message: err.Error(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package web_api
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -2,119 +2,651 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/go-grpc/maps"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SubmissionUpdate datastore.OptionalMap
|
var(
|
||||||
|
CreationPhaseSubmissionsLimit = 20
|
||||||
|
CreationPhaseSubmissionStatuses = []model.SubmissionStatus{
|
||||||
|
model.SubmissionStatusChangesRequested,
|
||||||
|
model.SubmissionStatusSubmitted,
|
||||||
|
model.SubmissionStatusUnderConstruction,
|
||||||
|
}
|
||||||
|
// limit mapfixes in the pipeline to one per target map
|
||||||
|
ActiveAcceptedSubmissionStatuses = []model.SubmissionStatus{
|
||||||
|
model.SubmissionStatusUploading,
|
||||||
|
model.SubmissionStatusValidated,
|
||||||
|
model.SubmissionStatusValidating,
|
||||||
|
model.SubmissionStatusAccepted,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func NewSubmissionUpdate() SubmissionUpdate {
|
var (
|
||||||
update := datastore.Optional()
|
ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
|
||||||
return SubmissionUpdate(update)
|
ErrUploadedAssetIDAlreadyExists = errors.New("The submission UploadedAssetID is already set")
|
||||||
|
ErrReleaseInvalidStatus = errors.New("Only submissions with Uploaded status can be released")
|
||||||
|
ErrReleaseNoUploadedAssetID = errors.New("Only submissions with a UploadedAssetID can be released")
|
||||||
|
ErrAcceptOwnSubmission = fmt.Errorf("%w: You cannot accept your own submission as the submitter", ErrPermissionDenied)
|
||||||
|
)
|
||||||
|
|
||||||
|
// POST /submissions
|
||||||
|
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionTriggerCreate) (*api.OperationID, error) {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
userId, err := userInfo.GetUserID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user's submissions in the creation phase exceeds the limit
|
||||||
|
{
|
||||||
|
filter := datastore.Optional()
|
||||||
|
filter.Add("submitter", int64(userId))
|
||||||
|
filter.Add("status_id", CreationPhaseSubmissionStatuses)
|
||||||
|
creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
|
Number: 1,
|
||||||
|
Size: int32(CreationPhaseSubmissionsLimit),
|
||||||
|
},datastore.ListSortDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if CreationPhaseSubmissionsLimit <= len(creation_submissions) {
|
||||||
|
return nil, ErrCreationPhaseSubmissionsLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
operation, err := svc.DB.Operations().Create(ctx, model.Operation{
|
||||||
|
Owner: int64(userId),
|
||||||
|
StatusID: model.OperationStatusCreated,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
create_request := model.CreateSubmissionRequest{
|
||||||
|
OperationID: operation.ID,
|
||||||
|
ModelID: request.AssetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(create_request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.submissions.create", []byte(j))
|
||||||
|
|
||||||
|
return &api.OperationID{
|
||||||
|
OperationID: operation.ID,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (update SubmissionUpdate) SetDisplayName(display_name string) {
|
// GetSubmission implements getSubmission operation.
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
//
|
||||||
}
|
// Retrieve map with ID.
|
||||||
func (update SubmissionUpdate) SetCreator(creator string) {
|
//
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
// GET /submissions/{SubmissionID}
|
||||||
}
|
func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionParams) (*api.Submission, error) {
|
||||||
func (update SubmissionUpdate) SetGameID(game_id uint32) {
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
func (update SubmissionUpdate) SetSubmitter(submitter uint64) {
|
}
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
return &api.Submission{
|
||||||
}
|
ID: submission.ID,
|
||||||
func (update SubmissionUpdate) SetAssetID(asset_id uint64) {
|
DisplayName: submission.DisplayName,
|
||||||
datastore.OptionalMap(update).Add("asset_id", asset_id)
|
Creator: submission.Creator,
|
||||||
}
|
GameID: submission.GameID,
|
||||||
func (update SubmissionUpdate) SetAssetVersion(asset_version uint64) {
|
CreatedAt: submission.CreatedAt.Unix(),
|
||||||
datastore.OptionalMap(update).Add("asset_version", asset_version)
|
UpdatedAt: submission.UpdatedAt.Unix(),
|
||||||
}
|
Submitter: int64(submission.Submitter),
|
||||||
func (update SubmissionUpdate) SetValidatedAssetID(validated_asset_id uint64) {
|
AssetID: int64(submission.AssetID),
|
||||||
datastore.OptionalMap(update).Add("validated_asset_id", validated_asset_id)
|
AssetVersion: int64(submission.AssetVersion),
|
||||||
}
|
Completed: submission.Completed,
|
||||||
func (update SubmissionUpdate) SetValidatedAssetVersion(validated_asset_version uint64) {
|
UploadedAssetID: api.NewOptInt64(int64(submission.UploadedAssetID)),
|
||||||
datastore.OptionalMap(update).Add("validated_asset_version", validated_asset_version)
|
StatusID: int32(submission.StatusID),
|
||||||
}
|
StatusMessage: submission.StatusMessage,
|
||||||
func (update SubmissionUpdate) SetCompleted(completed bool) {
|
}, nil
|
||||||
datastore.OptionalMap(update).Add("completed", completed)
|
|
||||||
}
|
|
||||||
func (update SubmissionUpdate) SetUploadedAssetID(uploaded_asset_id uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("uploaded_asset_id", uploaded_asset_id)
|
|
||||||
}
|
|
||||||
func (update SubmissionUpdate) SetStatusID(status_id model.SubmissionStatus) {
|
|
||||||
datastore.OptionalMap(update).Add("status_id", status_id)
|
|
||||||
}
|
|
||||||
func (update SubmissionUpdate) SetDescription(description string) {
|
|
||||||
datastore.OptionalMap(update).Add("description", description)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubmissionFilter datastore.OptionalMap
|
// ListSubmissions implements listSubmissions operation.
|
||||||
|
//
|
||||||
func NewSubmissionFilter(
|
// Get list of submissions.
|
||||||
) SubmissionFilter {
|
//
|
||||||
|
// GET /submissions
|
||||||
|
func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) ([]api.Submission, error) {
|
||||||
filter := datastore.Optional()
|
filter := datastore.Optional()
|
||||||
return SubmissionFilter(filter)
|
|
||||||
}
|
if params.DisplayName.IsSet(){
|
||||||
func (update SubmissionFilter) SetDisplayName(display_name string) {
|
filter.Add("display_name", params.DisplayName.Value)
|
||||||
datastore.OptionalMap(update).Add("display_name", display_name)
|
}
|
||||||
}
|
if params.Creator.IsSet(){
|
||||||
func (update SubmissionFilter) SetCreator(creator string) {
|
filter.Add("creator", params.Creator.Value)
|
||||||
datastore.OptionalMap(update).Add("creator", creator)
|
}
|
||||||
}
|
if params.GameID.IsSet(){
|
||||||
func (update SubmissionFilter) SetGameID(game_id uint32) {
|
filter.Add("game_id", params.GameID.Value)
|
||||||
datastore.OptionalMap(update).Add("game_id", game_id)
|
}
|
||||||
}
|
|
||||||
func (update SubmissionFilter) SetSubmitter(submitter uint64) {
|
sort := datastore.ListSort(params.Sort.Or(int32(datastore.ListSortDisabled)))
|
||||||
datastore.OptionalMap(update).Add("submitter", submitter)
|
|
||||||
}
|
items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
func (update SubmissionFilter) SetAssetID(asset_id uint64) {
|
Number: params.Page,
|
||||||
datastore.OptionalMap(update).Add("asset_id", asset_id)
|
Size: params.Limit,
|
||||||
}
|
},sort)
|
||||||
func (update SubmissionFilter) SetAssetVersion(asset_version uint64) {
|
if err != nil {
|
||||||
datastore.OptionalMap(update).Add("asset_version", asset_version)
|
return nil, err
|
||||||
}
|
}
|
||||||
func (update SubmissionFilter) SetUploadedAssetID(uploaded_asset_id uint64) {
|
|
||||||
datastore.OptionalMap(update).Add("uploaded_asset_id", uploaded_asset_id)
|
var resp []api.Submission
|
||||||
}
|
for _, item := range items {
|
||||||
func (update SubmissionFilter) SetStatuses(statuses []model.SubmissionStatus) {
|
resp = append(resp, api.Submission{
|
||||||
datastore.OptionalMap(update).Add("status_id", statuses)
|
ID: item.ID,
|
||||||
|
DisplayName: item.DisplayName,
|
||||||
|
Creator: item.Creator,
|
||||||
|
GameID: item.GameID,
|
||||||
|
CreatedAt: item.CreatedAt.Unix(),
|
||||||
|
UpdatedAt: item.UpdatedAt.Unix(),
|
||||||
|
Submitter: int64(item.Submitter),
|
||||||
|
AssetID: int64(item.AssetID),
|
||||||
|
AssetVersion: int64(item.AssetVersion),
|
||||||
|
Completed: item.Completed,
|
||||||
|
UploadedAssetID: api.NewOptInt64(int64(item.UploadedAssetID)),
|
||||||
|
StatusID: int32(item.StatusID),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) CreateSubmission(ctx context.Context, script model.Submission) (model.Submission, error) {
|
// PatchSubmissionCompleted implements patchSubmissionCompleted operation.
|
||||||
return svc.db.Submissions().Create(ctx, script)
|
//
|
||||||
|
// Retrieve map with ID.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/completed
|
||||||
|
func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSubmissionCompletedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleMaptest()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has MaptestGame role (request must originate from a maptest roblox game)
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMaptest
|
||||||
|
}
|
||||||
|
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.Add("completed", true)
|
||||||
|
return svc.DB.Submissions().Update(ctx, params.SubmissionID, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListSubmissions(ctx context.Context, filter SubmissionFilter, page model.Page, sort datastore.ListSort) ([]model.Submission, error) {
|
// UpdateSubmissionModel implements patchSubmissionModel operation.
|
||||||
return svc.db.Submissions().List(ctx, datastore.OptionalMap(filter), page, sort)
|
//
|
||||||
|
// Update model following role restrictions.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/model
|
||||||
|
func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.UpdateSubmissionModelParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read submission (this could be done with a transaction WHERE clause)
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.AddNotNil("asset_id", params.ModelID)
|
||||||
|
pmap.AddNotNil("asset_version", params.VersionID)
|
||||||
|
//always reset completed when model changes
|
||||||
|
pmap.Add("completed", false)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusChangesRequested, model.SubmissionStatusSubmitted, model.SubmissionStatusUnderConstruction}, pmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) ListSubmissionsWithTotal(ctx context.Context, filter SubmissionFilter, page model.Page, sort datastore.ListSort) (int64, []model.Submission, error) {
|
// ActionSubmissionReject invokes actionSubmissionReject operation.
|
||||||
return svc.db.Submissions().ListWithTotal(ctx, datastore.OptionalMap(filter), page, sort)
|
//
|
||||||
|
// Role Reviewer changes status from Submitted -> Rejected.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reject
|
||||||
|
func (svc *Service) ActionSubmissionReject(ctx context.Context, params api.ActionSubmissionRejectParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusRejected)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) DeleteSubmission(ctx context.Context, id int64) error {
|
// ActionSubmissionRequestChanges invokes actionSubmissionRequestChanges operation.
|
||||||
return svc.db.Submissions().Delete(ctx, id)
|
//
|
||||||
|
// Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/request-changes
|
||||||
|
func (svc *Service) ActionSubmissionRequestChanges(ctx context.Context, params api.ActionSubmissionRequestChangesParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusChangesRequested)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated, model.SubmissionStatusAccepted, model.SubmissionStatusSubmitted}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) GetSubmission(ctx context.Context, id int64) (model.Submission, error) {
|
// ActionSubmissionRevoke invokes actionSubmissionRevoke operation.
|
||||||
return svc.db.Submissions().Get(ctx, id)
|
//
|
||||||
|
// Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/revoke
|
||||||
|
func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.ActionSubmissionRevokeParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read submission (this could be done with a transaction WHERE clause)
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusUnderConstruction)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted, model.SubmissionStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) GetSubmissionList(ctx context.Context, ids []int64) ([]model.Submission, error) {
|
// ActionSubmissionSubmit invokes actionSubmissionSubmit operation.
|
||||||
return svc.db.Submissions().GetList(ctx, ids)
|
//
|
||||||
|
// Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/submit
|
||||||
|
func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.ActionSubmissionSubmitParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// read submission (this could be done with a transaction WHERE clause)
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.IsSubmitter(uint64(submission.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is the submitter
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNotSubmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusSubmitted)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUnderConstruction, model.SubmissionStatusChangesRequested}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateSubmission(ctx context.Context, id int64, pmap SubmissionUpdate) error {
|
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
|
||||||
return svc.db.Submissions().Update(ctx, id, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role Admin changes status from Validated -> Uploading.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-upload
|
||||||
|
func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params api.ActionSubmissionTriggerUploadParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionUpload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusUploading)
|
||||||
|
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidated}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel value because we are not using rust
|
||||||
|
if submission.UploadedAssetID == 0 {
|
||||||
|
// this is a new map
|
||||||
|
upload_new_request := model.UploadSubmissionRequest{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
ModelID: submission.ValidatedAssetID,
|
||||||
|
ModelVersion: submission.ValidatedAssetVersion,
|
||||||
|
// upload as displayname, whatever
|
||||||
|
ModelName: submission.DisplayName,
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(upload_new_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.submissions.upload", []byte(j))
|
||||||
|
} else {
|
||||||
|
// refuse to operate
|
||||||
|
return ErrUploadedAssetIDAlreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateSubmissionIfStatus(ctx context.Context, id int64, statuses []model.SubmissionStatus, pmap SubmissionUpdate) error {
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
return svc.db.Submissions().IfStatusThenUpdate(ctx, id, statuses, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role SubmissionRelease changes status from Uploading -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-uploading
|
||||||
|
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params api.ActionSubmissionValidatedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionUpload()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when submission was updated
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the submission was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidated)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *Service) UpdateAndGetSubmissionIfStatus(ctx context.Context, id int64, statuses []model.SubmissionStatus, pmap SubmissionUpdate) (model.Submission, error) {
|
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
|
||||||
return svc.db.Submissions().IfStatusThenUpdateAndGet(ctx, id, statuses, datastore.OptionalMap(pmap))
|
//
|
||||||
|
// Role Reviewer triggers validation and changes status from Submitted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/trigger-validate
|
||||||
|
func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params api.ActionSubmissionTriggerValidateParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// read submission (this could be done with a transaction WHERE clause)
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err = userInfo.IsSubmitter(uint64(submission.Submitter))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller is NOT the submitter
|
||||||
|
if has_role {
|
||||||
|
return ErrAcceptOwnSubmission
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidating)
|
||||||
|
submission, err = svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusSubmitted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_request := model.ValidateSubmissionRequest{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
ModelID: submission.AssetID,
|
||||||
|
ModelVersion: submission.AssetVersion,
|
||||||
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if submission.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &submission.ValidatedAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.submissions.validate", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionRetryValidate invokes actionSubmissionRetryValidate operation.
|
||||||
|
//
|
||||||
|
// Role Reviewer re-runs validation and changes status from Accepted -> Validating.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/retry-validate
|
||||||
|
func (svc *Service) ActionSubmissionRetryValidate(ctx context.Context, params api.ActionSubmissionRetryValidateParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidating)
|
||||||
|
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusAccepted}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_request := model.ValidateSubmissionRequest{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
ModelID: submission.AssetID,
|
||||||
|
ModelVersion: submission.AssetVersion,
|
||||||
|
ValidatedModelID: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sentinel values because we're not using rust
|
||||||
|
if submission.ValidatedAssetID != 0 {
|
||||||
|
validate_request.ValidatedModelID = &submission.ValidatedAssetID
|
||||||
|
}
|
||||||
|
|
||||||
|
j, err := json.Marshal(validate_request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.Nats.Publish("maptest.submissions.validate", []byte(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// Role SubmissionReview changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/reset-validating
|
||||||
|
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params api.ActionSubmissionAcceptedParams) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionReview()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleMapReview
|
||||||
|
}
|
||||||
|
|
||||||
|
// check when submission was updated
|
||||||
|
submission, err := svc.DB.Submissions().Get(ctx, params.SubmissionID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Before(submission.UpdatedAt.Add(time.Second*10)) {
|
||||||
|
// the last time the submission was updated must be longer than 10 seconds ago
|
||||||
|
return ErrDelayReset
|
||||||
|
}
|
||||||
|
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusAccepted)
|
||||||
|
smap.Add("status_message", "Manually forced reset")
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseSubmissions invokes releaseSubmissions operation.
|
||||||
|
//
|
||||||
|
// Release a set of uploaded maps.
|
||||||
|
//
|
||||||
|
// POST /release-submissions
|
||||||
|
func (svc *Service) ReleaseSubmissions(ctx context.Context, request []api.ReleaseInfo) error {
|
||||||
|
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
||||||
|
if !ok {
|
||||||
|
return ErrUserInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
has_role, err := userInfo.HasRoleSubmissionRelease()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check if caller has required role
|
||||||
|
if !has_role {
|
||||||
|
return ErrPermissionDeniedNeedRoleSubmissionRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
idList := make([]int64, len(request))
|
||||||
|
for i, releaseInfo := range request {
|
||||||
|
idList[i] = releaseInfo.SubmissionID
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch submissions
|
||||||
|
submissions, err := svc.DB.Submissions().GetList(ctx, idList)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check each submission to make sure it is ready to release
|
||||||
|
for _,submission := range submissions{
|
||||||
|
if submission.StatusID != model.SubmissionStatusUploaded{
|
||||||
|
return ErrReleaseInvalidStatus
|
||||||
|
}
|
||||||
|
if submission.UploadedAssetID == 0{
|
||||||
|
return ErrReleaseNoUploadedAssetID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i,submission := range submissions{
|
||||||
|
date := request[i].Date.Unix()
|
||||||
|
// create each map with go-grpc
|
||||||
|
_, err := svc.Client.Create(ctx, &maps.MapRequest{
|
||||||
|
ID: submission.UploadedAssetID,
|
||||||
|
DisplayName: &submission.DisplayName,
|
||||||
|
Creator: &submission.Creator,
|
||||||
|
GameID: &submission.GameID,
|
||||||
|
Date: &date,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update each status to Released
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusReleased)
|
||||||
|
err = svc.DB.Submissions().IfStatusThenUpdate(ctx, submission.ID, []model.SubmissionStatus{model.SubmissionStatusUploaded}, smap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
142
pkg/service_internal/mapfixes.go
Normal file
142
pkg/service_internal/mapfixes.go
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
// prevent two mapfixes with same asset id
|
||||||
|
ActiveMapfixStatuses = []model.MapfixStatus{
|
||||||
|
model.MapfixStatusUploading,
|
||||||
|
model.MapfixStatusValidated,
|
||||||
|
model.MapfixStatusValidating,
|
||||||
|
model.MapfixStatusAccepted,
|
||||||
|
model.MapfixStatusChangesRequested,
|
||||||
|
model.MapfixStatusSubmitted,
|
||||||
|
model.MapfixStatusUnderConstruction,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
ErrActiveMapfixSameAssetID = errors.New("There is an active mapfix with the same AssetID")
|
||||||
|
ErrNotAssetOwner = errors.New("You can only submit an asset you own")
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateMapfixValidatedModel implements patchMapfixModel operation.
|
||||||
|
//
|
||||||
|
// Update model following role restrictions.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/validated-model
|
||||||
|
func (svc *Service) UpdateMapfixValidatedModel(ctx context.Context, params internal.UpdateMapfixValidatedModelParams) error {
|
||||||
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.AddNotNil("validated_asset_id", params.ValidatedModelID)
|
||||||
|
pmap.AddNotNil("validated_asset_version", params.ValidatedModelVersion)
|
||||||
|
// DO NOT reset completed when validated model is updated
|
||||||
|
// pmap.Add("completed", false)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, pmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
||||||
|
//
|
||||||
|
// Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-validated
|
||||||
|
func (svc *Service) ActionMapfixValidated(ctx context.Context, params internal.ActionMapfixValidatedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusValidated)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-failed
|
||||||
|
func (svc *Service) ActionMapfixAccepted(ctx context.Context, params internal.ActionMapfixAcceptedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusAccepted)
|
||||||
|
smap.Add("status_message", params.StatusMessage)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /mapfixes/{MapfixID}/status/validator-uploaded
|
||||||
|
func (svc *Service) ActionMapfixUploaded(ctx context.Context, params internal.ActionMapfixUploadedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.MapfixStatusUploaded)
|
||||||
|
return svc.DB.Mapfixes().IfStatusThenUpdate(ctx, params.MapfixID, []model.MapfixStatus{model.MapfixStatusUploading}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST /mapfixes
|
||||||
|
func (svc *Service) CreateMapfix(ctx context.Context, request *internal.MapfixCreate) (*internal.MapfixID, error) {
|
||||||
|
// Check if an active mapfix with the same asset id exists
|
||||||
|
{
|
||||||
|
filter := datastore.Optional()
|
||||||
|
filter.Add("asset_id", request.AssetID)
|
||||||
|
filter.Add("asset_version", request.AssetVersion)
|
||||||
|
filter.Add("status_id", ActiveMapfixStatuses)
|
||||||
|
active_mapfixes, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
|
||||||
|
Number: 1,
|
||||||
|
Size: 1,
|
||||||
|
},datastore.ListSortDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(active_mapfixes) != 0{
|
||||||
|
return nil, ErrActiveMapfixSameAssetID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operation, err := svc.DB.Operations().Get(ctx, request.OperationID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if user owns asset
|
||||||
|
// TODO: allow bypass by admin
|
||||||
|
if operation.Owner != request.AssetOwner {
|
||||||
|
return nil, ErrNotAssetOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
mapfix, err := svc.DB.Mapfixes().Create(ctx, model.Mapfix{
|
||||||
|
ID: 0,
|
||||||
|
DisplayName: request.DisplayName,
|
||||||
|
Creator: request.Creator,
|
||||||
|
GameID: request.GameID,
|
||||||
|
Submitter: request.AssetOwner,
|
||||||
|
AssetID: request.AssetID,
|
||||||
|
AssetVersion: request.AssetVersion,
|
||||||
|
Completed: false,
|
||||||
|
TargetAssetID: request.TargetAssetID,
|
||||||
|
StatusID: model.MapfixStatusUnderConstruction,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark the operation as completed and provide the path
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.Add("status_id", model.OperationStatusCompleted)
|
||||||
|
pmap.Add("path", fmt.Sprintf("/mapfixes/%d", mapfix.ID))
|
||||||
|
err = svc.DB.Operations().Update(ctx, request.OperationID, pmap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &internal.MapfixID{
|
||||||
|
MapfixID: mapfix.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
21
pkg/service_internal/operations.go
Normal file
21
pkg/service_internal/operations.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionOperationFailed implements actionOperationFailed operation.
|
||||||
|
//
|
||||||
|
// Fail the specified OperationID with a StatusMessage.
|
||||||
|
//
|
||||||
|
// POST /operations/{OperationID}/status/operation-failed
|
||||||
|
func (svc *Service) ActionOperationFailed(ctx context.Context, params internal.ActionOperationFailedParams) (error) {
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.Add("status_id", model.OperationStatusFailed)
|
||||||
|
pmap.Add("status_message", params.StatusMessage)
|
||||||
|
return svc.DB.Operations().Update(ctx, params.OperationID, pmap)
|
||||||
|
}
|
||||||
80
pkg/service_internal/script_policy.go
Normal file
80
pkg/service_internal/script_policy.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateScriptPolicy implements createScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Create a new script policy.
|
||||||
|
//
|
||||||
|
// POST /script-policy
|
||||||
|
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ScriptPolicyID, error) {
|
||||||
|
from_script, err := svc.DB.Scripts().Get(ctx, req.FromScriptID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
|
||||||
|
|
||||||
|
script, err := svc.DB.ScriptPolicy().Create(ctx, model.ScriptPolicy{
|
||||||
|
ID: 0,
|
||||||
|
FromScriptHash: from_script.Hash,
|
||||||
|
ToScriptID: req.ToScriptID,
|
||||||
|
Policy: model.Policy(req.Policy),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ScriptPolicyID{
|
||||||
|
ScriptPolicyID: script.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListScriptPolicy implements listScriptPolicy operation.
|
||||||
|
//
|
||||||
|
// Get list of script policies.
|
||||||
|
//
|
||||||
|
// GET /script-policy
|
||||||
|
func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptPolicyParams) ([]api.ScriptPolicy, error) {
|
||||||
|
filter := datastore.Optional()
|
||||||
|
|
||||||
|
if params.FromScriptHash.IsSet(){
|
||||||
|
hash, err := model.HashParse(params.FromScriptHash.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
filter.AddNotNil("from_script_hash", int64(hash)) // No type safety!
|
||||||
|
}
|
||||||
|
if params.ToScriptID.IsSet(){
|
||||||
|
filter.AddNotNil("to_script_id", params.ToScriptID.Value)
|
||||||
|
}
|
||||||
|
if params.Policy.IsSet(){
|
||||||
|
filter.AddNotNil("policy", params.Policy.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := svc.DB.ScriptPolicy().List(ctx, filter, model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []api.ScriptPolicy
|
||||||
|
for _, item := range items {
|
||||||
|
resp = append(resp, api.ScriptPolicy{
|
||||||
|
ID: item.ID,
|
||||||
|
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
|
||||||
|
ToScriptID: item.ToScriptID,
|
||||||
|
Policy: int32(item.Policy),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
103
pkg/service_internal/scripts.go
Normal file
103
pkg/service_internal/scripts.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateScript implements createScript operation.
|
||||||
|
//
|
||||||
|
// Create a new script.
|
||||||
|
//
|
||||||
|
// POST /scripts
|
||||||
|
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ScriptID, error) {
|
||||||
|
script, err := svc.DB.Scripts().Create(ctx, model.Script{
|
||||||
|
ID: 0,
|
||||||
|
Name: req.Name,
|
||||||
|
Hash: int64(model.HashSource(req.Source)),
|
||||||
|
Source: req.Source,
|
||||||
|
ResourceType: model.ResourceType(req.ResourceType),
|
||||||
|
ResourceID: req.ResourceID.Or(0),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ScriptID{
|
||||||
|
ScriptID: script.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListScripts implements listScripts operation.
|
||||||
|
//
|
||||||
|
// Get list of scripts.
|
||||||
|
//
|
||||||
|
// GET /scripts
|
||||||
|
func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParams) ([]api.Script, error) {
|
||||||
|
filter := datastore.Optional()
|
||||||
|
|
||||||
|
if params.Hash.IsSet(){
|
||||||
|
hash, err := model.HashParse(params.Hash.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
filter.AddNotNil("hash", int64(hash)) // No type safety!
|
||||||
|
}
|
||||||
|
if params.Name.IsSet(){
|
||||||
|
filter.AddNotNil("name", params.Name.Value)
|
||||||
|
}
|
||||||
|
if params.Source.IsSet(){
|
||||||
|
filter.AddNotNil("source", params.Source.Value)
|
||||||
|
}
|
||||||
|
if params.ResourceType.IsSet(){
|
||||||
|
filter.AddNotNil("resource_type", params.ResourceType.Value)
|
||||||
|
}
|
||||||
|
if params.ResourceID.IsSet(){
|
||||||
|
filter.AddNotNil("resource_id", params.ResourceID.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := svc.DB.Scripts().List(ctx, filter, model.Page{
|
||||||
|
Number: params.Page,
|
||||||
|
Size: params.Limit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []api.Script
|
||||||
|
for _, item := range items {
|
||||||
|
resp = append(resp, api.Script{
|
||||||
|
ID: item.ID,
|
||||||
|
Hash: model.HashFormat(uint64(item.Hash)),
|
||||||
|
Source: item.Source,
|
||||||
|
ResourceType: int32(item.ResourceType),
|
||||||
|
ResourceID: item.ResourceID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetScript implements getScript operation.
|
||||||
|
//
|
||||||
|
// Get the specified script by ID.
|
||||||
|
//
|
||||||
|
// GET /scripts/{ScriptID}
|
||||||
|
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
|
||||||
|
script, err := svc.DB.Scripts().Get(ctx, params.ScriptID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.Script{
|
||||||
|
ID: script.ID,
|
||||||
|
Name: script.Name,
|
||||||
|
Hash: model.HashFormat(uint64(script.Hash)),
|
||||||
|
Source: script.Source,
|
||||||
|
ResourceType: int32(script.ResourceType),
|
||||||
|
ResourceID: script.ResourceID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
30
pkg/service_internal/service_internal.go
Normal file
30
pkg/service_internal/service_internal.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"github.com/nats-io/nats.go"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
DB datastore.Datastore
|
||||||
|
Nats nats.JetStreamContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// yay duplicate code
|
||||||
|
func (svc *Service) NewError(ctx context.Context, err error) *internal.ErrorStatusCode {
|
||||||
|
status := 500
|
||||||
|
if errors.Is(err, datastore.ErrNotExist) {
|
||||||
|
status = 404
|
||||||
|
}
|
||||||
|
return &internal.ErrorStatusCode{
|
||||||
|
StatusCode: status,
|
||||||
|
Response: internal.Error{
|
||||||
|
Code: int64(status),
|
||||||
|
Message: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
141
pkg/service_internal/submissions.go
Normal file
141
pkg/service_internal/submissions.go
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package service_internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
||||||
|
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
|
||||||
|
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
// prevent two mapfixes with same asset id
|
||||||
|
ActiveSubmissionStatuses = []model.SubmissionStatus{
|
||||||
|
model.SubmissionStatusUploading,
|
||||||
|
model.SubmissionStatusValidated,
|
||||||
|
model.SubmissionStatusValidating,
|
||||||
|
model.SubmissionStatusAccepted,
|
||||||
|
model.SubmissionStatusChangesRequested,
|
||||||
|
model.SubmissionStatusSubmitted,
|
||||||
|
model.SubmissionStatusUnderConstruction,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateSubmissionValidatedModel implements patchSubmissionModel operation.
|
||||||
|
//
|
||||||
|
// Update model following role restrictions.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/validated-model
|
||||||
|
func (svc *Service) UpdateSubmissionValidatedModel(ctx context.Context, params internal.UpdateSubmissionValidatedModelParams) error {
|
||||||
|
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.AddNotNil("validated_asset_id", params.ValidatedModelID)
|
||||||
|
pmap.AddNotNil("validated_asset_version", params.ValidatedModelVersion)
|
||||||
|
// DO NOT reset completed when validated model is updated
|
||||||
|
// pmap.Add("completed", false)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, pmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
||||||
|
//
|
||||||
|
// Role Validator changes status from Validating -> Validated.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-validated
|
||||||
|
func (svc *Service) ActionSubmissionValidated(ctx context.Context, params internal.ActionSubmissionValidatedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusValidated)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-failed
|
||||||
|
func (svc *Service) ActionSubmissionAccepted(ctx context.Context, params internal.ActionSubmissionAcceptedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusAccepted)
|
||||||
|
smap.Add("status_message", params.StatusMessage)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusValidating}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
||||||
|
//
|
||||||
|
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
||||||
|
//
|
||||||
|
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
||||||
|
func (svc *Service) ActionSubmissionUploaded(ctx context.Context, params internal.ActionSubmissionUploadedParams) error {
|
||||||
|
// transaction
|
||||||
|
smap := datastore.Optional()
|
||||||
|
smap.Add("status_id", model.SubmissionStatusUploaded)
|
||||||
|
smap.Add("uploaded_asset_id", params.UploadedAssetID)
|
||||||
|
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.SubmissionStatus{model.SubmissionStatusUploading}, smap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST /submissions
|
||||||
|
func (svc *Service) CreateSubmission(ctx context.Context, request *internal.SubmissionCreate) (*internal.SubmissionID, error) {
|
||||||
|
// Check if an active submission with the same asset id exists
|
||||||
|
{
|
||||||
|
filter := datastore.Optional()
|
||||||
|
filter.Add("asset_id", request.AssetID)
|
||||||
|
filter.Add("asset_version", request.AssetVersion)
|
||||||
|
filter.Add("status_id", ActiveSubmissionStatuses)
|
||||||
|
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
|
||||||
|
Number: 1,
|
||||||
|
Size: 1,
|
||||||
|
},datastore.ListSortDisabled)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(active_submissions) != 0{
|
||||||
|
return nil, ErrActiveSubmissionSameAssetID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operation, err := svc.DB.Operations().Get(ctx, request.OperationID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if user owns asset
|
||||||
|
// TODO: allow bypass by admin
|
||||||
|
if operation.Owner != request.AssetOwner {
|
||||||
|
return nil, ErrNotAssetOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
|
||||||
|
ID: 0,
|
||||||
|
DisplayName: request.DisplayName,
|
||||||
|
Creator: request.Creator,
|
||||||
|
GameID: request.GameID,
|
||||||
|
Submitter: request.AssetOwner,
|
||||||
|
AssetID: request.AssetID,
|
||||||
|
AssetVersion: request.AssetVersion,
|
||||||
|
Completed: false,
|
||||||
|
StatusID: model.SubmissionStatusUnderConstruction,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark the operation as completed and provide the path
|
||||||
|
pmap := datastore.Optional()
|
||||||
|
pmap.Add("status_id", model.OperationStatusCompleted)
|
||||||
|
pmap.Add("path", fmt.Sprintf("/submissions/%d", submission.ID))
|
||||||
|
err = svc.DB.Operations().Update(ctx, request.OperationID, pmap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &internal.SubmissionID{
|
||||||
|
SubmissionID: submission.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -1,380 +0,0 @@
|
|||||||
package validator_controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Mapfixes struct {
|
|
||||||
*validator.UnimplementedValidatorMapfixServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
func NewMapfixesController(
|
|
||||||
inner *service.Service,
|
|
||||||
) Mapfixes {
|
|
||||||
return Mapfixes{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var(
|
|
||||||
// prevent two mapfixes with same asset id
|
|
||||||
ActiveMapfixStatuses = []model.MapfixStatus{
|
|
||||||
model.MapfixStatusUploading,
|
|
||||||
model.MapfixStatusValidated,
|
|
||||||
model.MapfixStatusValidating,
|
|
||||||
model.MapfixStatusAcceptedUnvalidated,
|
|
||||||
model.MapfixStatusChangesRequested,
|
|
||||||
model.MapfixStatusSubmitted,
|
|
||||||
model.MapfixStatusUnderConstruction,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var(
|
|
||||||
ErrActiveMapfixSameAssetID = errors.New("There is an active mapfix with the same AssetID")
|
|
||||||
ErrNotAssetOwner = errors.New("You can only submit an asset you own")
|
|
||||||
)
|
|
||||||
|
|
||||||
// UpdateMapfixValidatedModel implements patchMapfixModel operation.
|
|
||||||
//
|
|
||||||
// Update model following role restrictions.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/validated-model
|
|
||||||
func (svc *Mapfixes) SetValidatedModel(ctx context.Context, params *validator.ValidatedModelRequest) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
|
|
||||||
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetValidatedAssetID(params.ValidatedModelID)
|
|
||||||
update.SetValidatedAssetVersion(params.ValidatedModelVersion)
|
|
||||||
// DO NOT reset completed when validated model is updated
|
|
||||||
// update.Add("completed", false)
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataChangeValidatedModel{
|
|
||||||
ValidatedModelID: params.ValidatedModelID,
|
|
||||||
ValidatedModelVersion: params.ValidatedModelVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventChangeValidatedModel(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixSubmitted invokes actionMapfixSubmitted operation.
|
|
||||||
//
|
|
||||||
// Role Validator changes status from Submitting -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/validator-submitted
|
|
||||||
func (svc *Mapfixes) SetStatusSubmitted(ctx context.Context, params *validator.SubmittedRequest) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.MapfixStatusSubmitted
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
update.SetAssetVersion(uint64(params.ModelVersion))
|
|
||||||
update.SetDisplayName(params.DisplayName)
|
|
||||||
update.SetCreator(params.Creator)
|
|
||||||
update.SetGameID(uint32(params.GameID))
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusSubmitting}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixRequestChanges implements actionMapfixRequestChanges operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Submitting -> RequestChanges.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/validator-request-changes
|
|
||||||
func (svc *Mapfixes) SetStatusRequestChanges(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.MapfixStatusChangesRequested
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusSubmitting}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixValidate invokes actionMapfixValidate operation.
|
|
||||||
//
|
|
||||||
// Role Validator changes status from Validating -> Validated.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/validator-validated
|
|
||||||
func (svc *Mapfixes) SetStatusValidated(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetStatusID(model.MapfixStatusValidated)
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixAccepted implements actionMapfixAccepted operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/validator-failed
|
|
||||||
func (svc *Mapfixes) SetStatusFailed(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.MapfixStatusAcceptedUnvalidated
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusValidating}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionMapfixUploaded implements actionMapfixUploaded operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/status/validator-uploaded
|
|
||||||
func (svc *Mapfixes) SetStatusUploaded(ctx context.Context, params *validator.MapfixID) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.MapfixStatusUploaded
|
|
||||||
update := service.NewMapfixUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allow_statuses := []model.MapfixStatus{model.MapfixStatusUploading}
|
|
||||||
err := svc.inner.UpdateMapfixIfStatus(ctx, MapfixID, allow_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMapfixAuditError implements createMapfixAuditError operation.
|
|
||||||
//
|
|
||||||
// Post an error to the audit log
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/error
|
|
||||||
func (svc *Mapfixes) CreateAuditError(ctx context.Context, params *validator.AuditErrorRequest) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := svc.inner.CreateAuditEventError(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMapfixAuditCheckList implements createMapfixAuditCheckList operation.
|
|
||||||
//
|
|
||||||
// Post a checklist to the audit log
|
|
||||||
//
|
|
||||||
// POST /mapfixes/{MapfixID}/checklist
|
|
||||||
func (svc *Mapfixes) CreateAuditChecklist(ctx context.Context, params *validator.AuditChecklistRequest) (*validator.NullResponse, error) {
|
|
||||||
MapfixID := int64(params.ID)
|
|
||||||
check_list := make([]model.Check, len(params.CheckList))
|
|
||||||
for i, check := range params.CheckList {
|
|
||||||
check_list[i] = model.Check{
|
|
||||||
Name: check.Name,
|
|
||||||
Summary: check.Summary,
|
|
||||||
Passed: check.Passed,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataCheckList{
|
|
||||||
CheckList: check_list,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := svc.inner.CreateAuditEventCheckList(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: MapfixID,
|
|
||||||
Type: model.ResourceMapfix,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST /mapfixes
|
|
||||||
func (svc *Mapfixes) Create(ctx context.Context, request *validator.MapfixCreate) (*validator.MapfixID, error) {
|
|
||||||
var Submitter=request.AssetOwner;
|
|
||||||
// Check if an active mapfix with the same asset id exists
|
|
||||||
{
|
|
||||||
filter := service.NewMapfixFilter()
|
|
||||||
filter.SetAssetID(request.AssetID)
|
|
||||||
filter.SetAssetVersion(request.AssetVersion)
|
|
||||||
filter.SetStatuses(ActiveMapfixStatuses)
|
|
||||||
active_mapfixes, err := svc.inner.ListMapfixes(ctx, filter, model.Page{
|
|
||||||
Number: 1,
|
|
||||||
Size: 1,
|
|
||||||
},datastore.ListSortDisabled)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(active_mapfixes) != 0{
|
|
||||||
return nil, ErrActiveMapfixSameAssetID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OperationID := int32(request.OperationID)
|
|
||||||
operation, err := svc.inner.GetOperation(ctx, OperationID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if user owns asset
|
|
||||||
// TODO: allow bypass by admin
|
|
||||||
if operation.Owner != Submitter {
|
|
||||||
return nil, ErrNotAssetOwner
|
|
||||||
}
|
|
||||||
|
|
||||||
mapfix, err := svc.inner.CreateMapfix(ctx, model.Mapfix{
|
|
||||||
ID: 0,
|
|
||||||
DisplayName: request.DisplayName,
|
|
||||||
Creator: request.Creator,
|
|
||||||
GameID: request.GameID,
|
|
||||||
Submitter: Submitter,
|
|
||||||
AssetID: request.AssetID,
|
|
||||||
AssetVersion: request.AssetVersion,
|
|
||||||
Completed: false,
|
|
||||||
TargetAssetID: request.TargetAssetID,
|
|
||||||
StatusID: model.MapfixStatusUnderConstruction,
|
|
||||||
Description: request.Description,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark the operation as completed and provide the path
|
|
||||||
params := service.NewOperationCompleteParams(fmt.Sprintf("/mapfixes/%d", mapfix.ID))
|
|
||||||
err = svc.inner.CompleteOperation(ctx, OperationID, params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.MapfixID{
|
|
||||||
ID: uint64(mapfix.ID),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package validator_controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Operations struct {
|
|
||||||
*validator.UnimplementedValidatorOperationServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
func NewOperationsController(
|
|
||||||
inner *service.Service,
|
|
||||||
) Operations {
|
|
||||||
return Operations{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionOperationFailed implements actionOperationFailed operation.
|
|
||||||
//
|
|
||||||
// Fail the specified OperationID with a StatusMessage.
|
|
||||||
//
|
|
||||||
// POST /operations/{OperationID}/status/operation-failed
|
|
||||||
func (svc *Operations) Fail(ctx context.Context, params *validator.OperationFailRequest) (*validator.NullResponse, error) {
|
|
||||||
fail_params := service.NewOperationFailParams(
|
|
||||||
params.StatusMessage,
|
|
||||||
)
|
|
||||||
err := svc.inner.FailOperation(ctx, int32(params.OperationID), fail_params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package validator_controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ScriptPolicy struct {
|
|
||||||
*validator.UnimplementedValidatorScriptPolicyServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
func NewScriptPolicyController(
|
|
||||||
inner *service.Service,
|
|
||||||
) ScriptPolicy {
|
|
||||||
return ScriptPolicy{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateScriptPolicy implements createScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Create a new script policy.
|
|
||||||
//
|
|
||||||
// POST /script-policy
|
|
||||||
func (svc *ScriptPolicy) Create(ctx context.Context, req *validator.ScriptPolicyCreate) (*validator.ScriptPolicyID, error) {
|
|
||||||
from_script, err := svc.inner.GetScript(ctx, int64(req.FromScriptID))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
|
|
||||||
|
|
||||||
script, err := svc.inner.CreateScriptPolicy(ctx, model.ScriptPolicy{
|
|
||||||
ID: 0,
|
|
||||||
FromScriptHash: from_script.Hash,
|
|
||||||
ToScriptID: int64(req.ToScriptID),
|
|
||||||
Policy: model.Policy(req.Policy),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.ScriptPolicyID{
|
|
||||||
ID: uint64(script.ID),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListScriptPolicy implements listScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Get list of script policies.
|
|
||||||
//
|
|
||||||
// GET /script-policy
|
|
||||||
func (svc *ScriptPolicy) List(ctx context.Context, params *validator.ScriptPolicyListRequest) (*validator.ScriptPolicyListResponse, error) {
|
|
||||||
filter := service.NewScriptPolicyFilter()
|
|
||||||
|
|
||||||
if params.Filter.FromScriptHash != nil {
|
|
||||||
filter.SetFromScriptHash(int64(*params.Filter.FromScriptHash))
|
|
||||||
}
|
|
||||||
if params.Filter.ToScriptID != nil {
|
|
||||||
filter.SetToScriptID(int64(*params.Filter.ToScriptID))
|
|
||||||
}
|
|
||||||
if params.Filter.Policy != nil {
|
|
||||||
filter.SetPolicy(int32(*params.Filter.Policy))
|
|
||||||
}
|
|
||||||
|
|
||||||
items, err := svc.inner.ListScriptPolicies(ctx, filter, model.Page{
|
|
||||||
Number: int32(params.Page.Number),
|
|
||||||
Size: int32(params.Page.Size),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := validator.ScriptPolicyListResponse{}
|
|
||||||
resp.ScriptPolicies = make([]*validator.ScriptPolicy, len(items))
|
|
||||||
for i, item := range items {
|
|
||||||
resp.ScriptPolicies[i] = &validator.ScriptPolicy{
|
|
||||||
ID: uint64(item.ID),
|
|
||||||
FromScriptHash: uint64(item.FromScriptHash),
|
|
||||||
ToScriptID: uint64(item.ToScriptID),
|
|
||||||
Policy: validator.Policy(int32(item.Policy)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
package validator_controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Scripts struct {
|
|
||||||
*validator.UnimplementedValidatorScriptServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
func NewScriptsController(
|
|
||||||
inner *service.Service,
|
|
||||||
) Scripts {
|
|
||||||
return Scripts{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateScript implements createScript operation.
|
|
||||||
//
|
|
||||||
// Create a new script.
|
|
||||||
//
|
|
||||||
// POST /scripts
|
|
||||||
func (svc *Scripts) Create(ctx context.Context, req *validator.ScriptCreate) (*validator.ScriptID, error) {
|
|
||||||
ResourceID := int64(0)
|
|
||||||
if req.ResourceID != nil {
|
|
||||||
ResourceID = int64(*req.ResourceID)
|
|
||||||
}
|
|
||||||
script, err := svc.inner.CreateScript(ctx, model.Script{
|
|
||||||
ID: 0,
|
|
||||||
Name: req.Name,
|
|
||||||
Hash: int64(model.HashSource(req.Source)),
|
|
||||||
Source: req.Source,
|
|
||||||
ResourceType: model.ResourceType(req.ResourceType),
|
|
||||||
ResourceID: ResourceID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.ScriptID{
|
|
||||||
ID: uint64(script.ID),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListScripts implements listScripts operation.
|
|
||||||
//
|
|
||||||
// Get list of scripts.
|
|
||||||
//
|
|
||||||
// GET /scripts
|
|
||||||
func (svc *Scripts) List(ctx context.Context, params *validator.ScriptListRequest) (*validator.ScriptListResponse, error) {
|
|
||||||
filter := service.NewScriptFilter()
|
|
||||||
if params.Filter.Hash != nil {
|
|
||||||
filter.SetHash(int64(*params.Filter.Hash))
|
|
||||||
}
|
|
||||||
if params.Filter.Name != nil {
|
|
||||||
filter.SetName(*params.Filter.Name)
|
|
||||||
}
|
|
||||||
if params.Filter.Source != nil {
|
|
||||||
filter.SetSource(*params.Filter.Source)
|
|
||||||
}
|
|
||||||
if params.Filter.ResourceType != nil {
|
|
||||||
filter.SetResourceType(int32(*params.Filter.ResourceType))
|
|
||||||
}
|
|
||||||
if params.Filter.ResourceID != nil {
|
|
||||||
filter.SetResourceID(int64(*params.Filter.ResourceID))
|
|
||||||
}
|
|
||||||
|
|
||||||
items, err := svc.inner.ListScripts(ctx, filter, model.Page{
|
|
||||||
Number: int32(params.Page.Number),
|
|
||||||
Size: int32(params.Page.Size),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := validator.ScriptListResponse{}
|
|
||||||
resp.Scripts = make([]*validator.Script, len(items))
|
|
||||||
for i, item := range items {
|
|
||||||
resource_id := uint64(item.ResourceID)
|
|
||||||
resp.Scripts[i] = &validator.Script{
|
|
||||||
ID: uint64(item.ID),
|
|
||||||
Name: item.Name,
|
|
||||||
Hash: uint64(item.Hash),
|
|
||||||
Source: item.Source,
|
|
||||||
ResourceType: validator.ResourceType(item.ResourceType),
|
|
||||||
ResourceID: &resource_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetScript implements getScript operation.
|
|
||||||
//
|
|
||||||
// Get the specified script by ID.
|
|
||||||
//
|
|
||||||
// GET /scripts/{ScriptID}
|
|
||||||
func (svc *Scripts) Get(ctx context.Context, params *validator.ScriptID) (*validator.Script, error) {
|
|
||||||
ScriptID := int64(params.ID)
|
|
||||||
script, err := svc.inner.GetScript(ctx, ScriptID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceID := uint64(script.ResourceID)
|
|
||||||
return &validator.Script{
|
|
||||||
ID: uint64(script.ID),
|
|
||||||
Name: script.Name,
|
|
||||||
Hash: uint64(script.Hash),
|
|
||||||
Source: script.Source,
|
|
||||||
ResourceType: validator.ResourceType(script.ResourceType),
|
|
||||||
ResourceID: &ResourceID,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
package validator_controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/go-grpc/validator"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Submissions struct {
|
|
||||||
*validator.UnimplementedValidatorSubmissionServiceServer
|
|
||||||
inner *service.Service
|
|
||||||
}
|
|
||||||
func NewSubmissionsController(
|
|
||||||
inner *service.Service,
|
|
||||||
) Submissions {
|
|
||||||
return Submissions{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var(
|
|
||||||
// prevent two mapfixes with same asset id
|
|
||||||
ActiveSubmissionStatuses = []model.SubmissionStatus{
|
|
||||||
model.SubmissionStatusUploading,
|
|
||||||
model.SubmissionStatusValidated,
|
|
||||||
model.SubmissionStatusValidating,
|
|
||||||
model.SubmissionStatusAcceptedUnvalidated,
|
|
||||||
model.SubmissionStatusChangesRequested,
|
|
||||||
model.SubmissionStatusSubmitted,
|
|
||||||
model.SubmissionStatusUnderConstruction,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var(
|
|
||||||
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
|
|
||||||
)
|
|
||||||
|
|
||||||
// UpdateSubmissionValidatedModel implements patchSubmissionModel operation.
|
|
||||||
//
|
|
||||||
// Update model following role restrictions.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/validated-model
|
|
||||||
func (svc *Submissions) SetValidatedModel(ctx context.Context, params *validator.ValidatedModelRequest) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
|
|
||||||
// check if Status is ChangesRequested|Submitted|UnderConstruction
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetValidatedAssetID(params.ValidatedModelID)
|
|
||||||
update.SetValidatedAssetVersion(params.ValidatedModelVersion)
|
|
||||||
// DO NOT reset completed when validated model is updated
|
|
||||||
// update.Add("completed", false)
|
|
||||||
allowed_statuses := []model.SubmissionStatus{model.SubmissionStatusValidating}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataChangeValidatedModel{
|
|
||||||
ValidatedModelID: params.ValidatedModelID,
|
|
||||||
ValidatedModelVersion: params.ValidatedModelVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventChangeValidatedModel(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionSubmitted invokes actionSubmissionSubmitted operation.
|
|
||||||
//
|
|
||||||
// Role Validator changes status from Submitting -> Submitted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/validator-submitted
|
|
||||||
func (svc *Submissions) SetStatusSubmitted(ctx context.Context, params *validator.SubmittedRequest) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.SubmissionStatusSubmitted
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
update.SetAssetVersion(uint64(params.ModelVersion))
|
|
||||||
update.SetDisplayName(params.DisplayName)
|
|
||||||
update.SetCreator(params.Creator)
|
|
||||||
update.SetGameID(uint32(params.GameID))
|
|
||||||
allowed_statuses := []model.SubmissionStatus{model.SubmissionStatusSubmitting}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionRequestChanges implements actionSubmissionRequestChanges operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Submitting -> RequestChanges.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/validator-request-changes
|
|
||||||
func (svc *Submissions) SetStatusRequestChanges(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.SubmissionStatusChangesRequested
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusSubmitting}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
|
|
||||||
//
|
|
||||||
// Role Validator changes status from Validating -> Validated.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/validator-validated
|
|
||||||
func (svc *Submissions) SetStatusValidated(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.SubmissionStatusValidated
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusValidating}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionAccepted implements actionSubmissionAccepted operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Validating -> Accepted.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/validator-failed
|
|
||||||
func (svc *Submissions) SetStatusFailed(ctx context.Context, params *validator.SubmissionID) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.SubmissionStatusAcceptedUnvalidated
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusValidating}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// push an action audit event
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
|
|
||||||
//
|
|
||||||
// (Internal endpoint) Role Validator changes status from Uploading -> Uploaded.
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/status/validator-uploaded
|
|
||||||
func (svc *Submissions) SetStatusUploaded(ctx context.Context, params *validator.StatusUploadedRequest) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
// transaction
|
|
||||||
target_status := model.SubmissionStatusUploaded
|
|
||||||
update := service.NewSubmissionUpdate()
|
|
||||||
update.SetStatusID(target_status)
|
|
||||||
update.SetUploadedAssetID(params.UploadedAssetID)
|
|
||||||
allowed_statuses :=[]model.SubmissionStatus{model.SubmissionStatusUploading}
|
|
||||||
err := svc.inner.UpdateSubmissionIfStatus(ctx, SubmissionID, allowed_statuses, update)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataAction{
|
|
||||||
TargetStatus: uint32(target_status),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svc.inner.CreateAuditEventAction(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSubmissionAuditError implements createSubmissionAuditError operation.
|
|
||||||
//
|
|
||||||
// Post an error to the audit log
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/error
|
|
||||||
func (svc *Submissions) CreateAuditError(ctx context.Context, params *validator.AuditErrorRequest) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
event_data := model.AuditEventDataError{
|
|
||||||
Error: params.ErrorMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := svc.inner.CreateAuditEventError(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSubmissionAuditCheckList implements createSubmissionAuditCheckList operation.
|
|
||||||
//
|
|
||||||
// Post a checklist to the audit log
|
|
||||||
//
|
|
||||||
// POST /submissions/{SubmissionID}/checklist
|
|
||||||
func (svc *Submissions) CreateAuditChecklist(ctx context.Context, params *validator.AuditChecklistRequest) (*validator.NullResponse, error) {
|
|
||||||
SubmissionID := int64(params.ID)
|
|
||||||
check_list := make([]model.Check, len(params.CheckList))
|
|
||||||
for i, check := range params.CheckList {
|
|
||||||
check_list[i] = model.Check{
|
|
||||||
Name: check.Name,
|
|
||||||
Summary: check.Summary,
|
|
||||||
Passed: check.Passed,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event_data := model.AuditEventDataCheckList{
|
|
||||||
CheckList: check_list,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := svc.inner.CreateAuditEventCheckList(
|
|
||||||
ctx,
|
|
||||||
model.ValidatorUserID,
|
|
||||||
model.Resource{
|
|
||||||
ID: SubmissionID,
|
|
||||||
Type: model.ResourceSubmission,
|
|
||||||
},
|
|
||||||
event_data,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.NullResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST /submissions
|
|
||||||
func (svc *Submissions) Create(ctx context.Context, request *validator.SubmissionCreate) (*validator.SubmissionID, error) {
|
|
||||||
var Submitter=uint64(request.AssetOwner);
|
|
||||||
var Status=model.SubmissionStatus(request.Status);
|
|
||||||
var roles=model.Roles(request.Roles);
|
|
||||||
|
|
||||||
// Check if an active submission with the same asset id exists
|
|
||||||
{
|
|
||||||
filter := service.NewSubmissionFilter()
|
|
||||||
filter.SetAssetID(request.AssetID)
|
|
||||||
filter.SetAssetVersion(request.AssetVersion)
|
|
||||||
filter.SetStatuses(ActiveSubmissionStatuses)
|
|
||||||
active_submissions, err := svc.inner.ListSubmissions(ctx, filter, model.Page{
|
|
||||||
Number: 1,
|
|
||||||
Size: 1,
|
|
||||||
},datastore.ListSortDisabled)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(active_submissions) != 0{
|
|
||||||
return nil, ErrActiveSubmissionSameAssetID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operation_id := int32(request.OperationID)
|
|
||||||
operation, err := svc.inner.GetOperation(ctx, operation_id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if user owns asset
|
|
||||||
is_submitter := operation.Owner == Submitter
|
|
||||||
// check if user is map admin
|
|
||||||
has_submission_review := roles & model.RolesSubmissionReview == model.RolesSubmissionReview
|
|
||||||
// if neither, u not allowed
|
|
||||||
if !is_submitter && !has_submission_review {
|
|
||||||
return nil, ErrNotAssetOwner
|
|
||||||
}
|
|
||||||
|
|
||||||
submission, err := svc.inner.CreateSubmission(ctx, model.Submission{
|
|
||||||
ID: 0,
|
|
||||||
DisplayName: request.DisplayName,
|
|
||||||
Creator: request.Creator,
|
|
||||||
GameID: request.GameID,
|
|
||||||
Submitter: Submitter,
|
|
||||||
AssetID: request.AssetID,
|
|
||||||
AssetVersion: request.AssetVersion,
|
|
||||||
Completed: false,
|
|
||||||
StatusID: Status,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark the operation as completed and provide the path
|
|
||||||
params := service.NewOperationCompleteParams(fmt.Sprintf("/submissions/%d", submission.ID))
|
|
||||||
err = svc.inner.CompleteOperation(ctx, operation_id, params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &validator.SubmissionID{
|
|
||||||
ID: uint64(submission.ID),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,140 +0,0 @@
|
|||||||
package web_api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/roblox"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MigrateMaps implements migrateMaps operation.
|
|
||||||
//
|
|
||||||
// Perform maps migration.
|
|
||||||
//
|
|
||||||
// POST /migrate
|
|
||||||
func (svc *Service) MigrateMaps(ctx context.Context) (error) {
|
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !ok {
|
|
||||||
return ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleSubmissionRelease()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has_role {
|
|
||||||
return ErrPermissionDeniedNeedRoleSubmissionRelease
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc.inner.TEMP_DoMapsMigration(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMaps implements listMaps operation.
|
|
||||||
//
|
|
||||||
// Get list of maps.
|
|
||||||
//
|
|
||||||
// GET /maps
|
|
||||||
func (svc *Service) ListMaps(ctx context.Context, params api.ListMapsParams) ([]api.Map, error) {
|
|
||||||
filter := service.NewMapFilter()
|
|
||||||
|
|
||||||
if display_name, display_name_ok := params.DisplayName.Get(); display_name_ok{
|
|
||||||
filter.SetDisplayName(display_name)
|
|
||||||
}
|
|
||||||
if creator, creator_ok := params.Creator.Get(); creator_ok{
|
|
||||||
filter.SetCreator(creator)
|
|
||||||
}
|
|
||||||
if game_id, game_id_ok := params.GameID.Get(); game_id_ok{
|
|
||||||
filter.SetGameID(uint32(game_id))
|
|
||||||
}
|
|
||||||
|
|
||||||
items, err := svc.inner.ListMaps(ctx,
|
|
||||||
filter,
|
|
||||||
model.Page{
|
|
||||||
Size: params.Limit,
|
|
||||||
Number: params.Page,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp []api.Map
|
|
||||||
for _, item := range items {
|
|
||||||
resp = append(resp, api.Map{
|
|
||||||
ID: item.ID,
|
|
||||||
DisplayName: item.DisplayName,
|
|
||||||
Creator: item.Creator,
|
|
||||||
GameID: int32(item.GameID),
|
|
||||||
Date: item.Date.Unix(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMap implements getScript operation.
|
|
||||||
//
|
|
||||||
// Get the specified script by ID.
|
|
||||||
//
|
|
||||||
// GET /maps/{MapID}
|
|
||||||
func (svc *Service) GetMap(ctx context.Context, params api.GetMapParams) (*api.Map, error) {
|
|
||||||
mapResponse, err := svc.inner.GetMap(ctx, params.MapID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.Map{
|
|
||||||
ID: mapResponse.ID,
|
|
||||||
DisplayName: mapResponse.DisplayName,
|
|
||||||
Creator: mapResponse.Creator,
|
|
||||||
GameID: int32(mapResponse.GameID),
|
|
||||||
Date: mapResponse.Date.Unix(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DownloadMapAsset invokes downloadMapAsset operation.
|
|
||||||
//
|
|
||||||
// Download the map asset.
|
|
||||||
//
|
|
||||||
// GET /maps/{MapID}/download
|
|
||||||
func (svc *Service) DownloadMapAsset(ctx context.Context, params api.DownloadMapAssetParams) (ok api.DownloadMapAssetOK, err error) {
|
|
||||||
userInfo, success := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !success {
|
|
||||||
return ok, ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleMapDownload()
|
|
||||||
if err != nil {
|
|
||||||
return ok, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has_role {
|
|
||||||
return ok, ErrPermissionDeniedNeedRoleMapDownload
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure map exists in the db!
|
|
||||||
// This could otherwise be used to access any asset
|
|
||||||
_, err = svc.inner.GetMap(ctx, 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// download the complete file
|
|
||||||
asset, err := svc.roblox.DownloadAsset(info)
|
|
||||||
if err != nil{
|
|
||||||
return ok, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ok.Data = asset
|
|
||||||
return ok, nil
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package web_api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetOperation implements getOperation operation.
|
|
||||||
//
|
|
||||||
// Get the specified operation by ID.
|
|
||||||
//
|
|
||||||
// GET /operations/{OperationID}
|
|
||||||
func (svc *Service) GetOperation(ctx context.Context, params api.GetOperationParams) (*api.Operation, error) {
|
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !ok {
|
|
||||||
return nil, ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
// You must be the operation owner to read it
|
|
||||||
|
|
||||||
operation, err := svc.inner.GetOperation(ctx, params.OperationID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
userId, err := userInfo.GetUserID()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if caller is the submitter
|
|
||||||
has_role := userId == operation.Owner
|
|
||||||
if !has_role {
|
|
||||||
return nil, ErrPermissionDeniedNotSubmitter
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.Operation{
|
|
||||||
OperationID: operation.ID,
|
|
||||||
Date: operation.CreatedAt.Unix(),
|
|
||||||
Owner: int64(operation.Owner),
|
|
||||||
Status: int32(operation.StatusID),
|
|
||||||
StatusMessage: operation.StatusMessage,
|
|
||||||
Path: operation.Path,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
package web_api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateScriptPolicy implements createScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Create a new script policy.
|
|
||||||
//
|
|
||||||
// POST /script-policy
|
|
||||||
func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolicyCreate) (*api.ScriptPolicyID, error) {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
from_script, err := svc.inner.GetScript(ctx, req.FromScriptID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// the existence of ToScriptID does not need to be validated because it's checked by a foreign key constraint.
|
|
||||||
|
|
||||||
script, err := svc.inner.CreateScriptPolicy(ctx, model.ScriptPolicy{
|
|
||||||
ID: 0,
|
|
||||||
FromScriptHash: from_script.Hash,
|
|
||||||
ToScriptID: req.ToScriptID,
|
|
||||||
Policy: model.Policy(req.Policy),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.ScriptPolicyID{
|
|
||||||
ScriptPolicyID: script.ID,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ListScriptPolicy implements listScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Get list of script policies.
|
|
||||||
//
|
|
||||||
// GET /script-policy
|
|
||||||
func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptPolicyParams) ([]api.ScriptPolicy, error) {
|
|
||||||
filter := service.NewScriptPolicyFilter()
|
|
||||||
|
|
||||||
if hash_hex, ok := params.FromScriptHash.Get(); ok{
|
|
||||||
hash_parsed, err := model.HashParse(hash_hex)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
filter.SetFromScriptHash(int64(hash_parsed))
|
|
||||||
}
|
|
||||||
if to_script_id, to_script_id_ok := params.ToScriptID.Get(); to_script_id_ok{
|
|
||||||
filter.SetToScriptID(to_script_id)
|
|
||||||
}
|
|
||||||
if policy, policy_ok := params.Policy.Get(); policy_ok{
|
|
||||||
filter.SetPolicy(policy)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
items, err := svc.inner.ListScriptPolicies(ctx, filter, model.Page{
|
|
||||||
Number: params.Page,
|
|
||||||
Size: params.Limit,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp []api.ScriptPolicy
|
|
||||||
for _, item := range items {
|
|
||||||
resp = append(resp, api.ScriptPolicy{
|
|
||||||
ID: item.ID,
|
|
||||||
FromScriptHash: model.HashFormat(uint64(item.FromScriptHash)),
|
|
||||||
ToScriptID: item.ToScriptID,
|
|
||||||
Policy: int32(item.Policy),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteScriptPolicy implements deleteScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Delete the specified script policy by ID.
|
|
||||||
//
|
|
||||||
// DELETE /script-policy/{ScriptPolicyID}
|
|
||||||
func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScriptPolicyParams) error {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc.inner.DeleteScriptPolicy(ctx, params.ScriptPolicyID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetScriptPolicy implements getScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Get the specified script policy by ID.
|
|
||||||
//
|
|
||||||
// GET /script-policy/{ScriptPolicyID}
|
|
||||||
func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPolicyParams) (*api.ScriptPolicy, error) {
|
|
||||||
policy, err := svc.inner.GetScriptPolicy(ctx, params.ScriptPolicyID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.ScriptPolicy{
|
|
||||||
ID: policy.ID,
|
|
||||||
FromScriptHash: model.HashFormat(uint64(policy.FromScriptHash)),
|
|
||||||
ToScriptID: policy.ToScriptID,
|
|
||||||
Policy: int32(policy.Policy),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateScriptPolicy implements updateScriptPolicy operation.
|
|
||||||
//
|
|
||||||
// Update the specified script policy by ID.
|
|
||||||
//
|
|
||||||
// POST /script-policy/{ScriptPolicyID}
|
|
||||||
func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolicyUpdate, params api.UpdateScriptPolicyParams) error {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := service.NewScriptPolicyFilter()
|
|
||||||
if from_script_id, ok := req.FromScriptID.Get(); ok {
|
|
||||||
from_script, err := svc.inner.GetScript(ctx, from_script_id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
filter.SetFromScriptHash(from_script.Hash)
|
|
||||||
}
|
|
||||||
if to_script_id, to_script_id_ok := req.ToScriptID.Get(); to_script_id_ok{
|
|
||||||
filter.SetToScriptID(to_script_id)
|
|
||||||
}
|
|
||||||
if policy, policy_ok := req.Policy.Get(); policy_ok{
|
|
||||||
filter.SetPolicy(policy)
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc.inner.UpdateScriptPolicy(ctx, req.ID, filter)
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
package web_api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/model"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CheckHasRoleScriptWrite(ctx context.Context) error {
|
|
||||||
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
|
|
||||||
if !ok {
|
|
||||||
return ErrUserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
has_role, err := userInfo.HasRoleScriptWrite()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !has_role {
|
|
||||||
return ErrPermissionDeniedNeedRoleScriptWrite
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateScript implements createScript operation.
|
|
||||||
//
|
|
||||||
// Create a new script.
|
|
||||||
//
|
|
||||||
// POST /scripts
|
|
||||||
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ScriptID, error) {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
script, err := svc.inner.CreateScript(ctx, model.Script{
|
|
||||||
ID: 0,
|
|
||||||
Name: req.Name,
|
|
||||||
Hash: int64(model.HashSource(req.Source)),
|
|
||||||
Source: req.Source,
|
|
||||||
ResourceType: model.ResourceType(req.ResourceType),
|
|
||||||
ResourceID: req.ResourceID.Or(0),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.ScriptID{
|
|
||||||
ScriptID: script.ID,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListScripts implements listScripts operation.
|
|
||||||
//
|
|
||||||
// Get list of scripts.
|
|
||||||
//
|
|
||||||
// GET /scripts
|
|
||||||
func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParams) ([]api.Script, error) {
|
|
||||||
filter := service.NewScriptFilter()
|
|
||||||
|
|
||||||
if hash_hex, ok := params.Hash.Get(); ok{
|
|
||||||
hash_parsed, err := model.HashParse(hash_hex)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
filter.SetHash(int64(hash_parsed))
|
|
||||||
}
|
|
||||||
if name, name_ok := params.Name.Get(); name_ok{
|
|
||||||
filter.SetName(name)
|
|
||||||
}
|
|
||||||
if source, source_ok := params.Source.Get(); source_ok{
|
|
||||||
filter.SetSource(source)
|
|
||||||
}
|
|
||||||
if resource_type, resource_type_ok := params.ResourceType.Get(); resource_type_ok{
|
|
||||||
filter.SetResourceType(resource_type)
|
|
||||||
}
|
|
||||||
if resource_id, resource_id_ok := params.ResourceID.Get(); resource_id_ok{
|
|
||||||
filter.SetResourceID(resource_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
items, err := svc.inner.ListScripts(ctx, filter, model.Page{
|
|
||||||
Number: params.Page,
|
|
||||||
Size: params.Limit,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp []api.Script
|
|
||||||
for _, item := range items {
|
|
||||||
resp = append(resp, api.Script{
|
|
||||||
ID: item.ID,
|
|
||||||
Name: item.Name,
|
|
||||||
Hash: model.HashFormat(uint64(item.Hash)),
|
|
||||||
Source: item.Source,
|
|
||||||
ResourceType: int32(item.ResourceType),
|
|
||||||
ResourceID: item.ResourceID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteScript implements deleteScript operation.
|
|
||||||
//
|
|
||||||
// Delete the specified script by ID.
|
|
||||||
//
|
|
||||||
// DELETE /scripts/{ScriptID}
|
|
||||||
func (svc *Service) DeleteScript(ctx context.Context, params api.DeleteScriptParams) error {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc.inner.DeleteScript(ctx, params.ScriptID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetScript implements getScript operation.
|
|
||||||
//
|
|
||||||
// Get the specified script by ID.
|
|
||||||
//
|
|
||||||
// GET /scripts/{ScriptID}
|
|
||||||
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
|
|
||||||
script, err := svc.inner.GetScript(ctx, params.ScriptID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &api.Script{
|
|
||||||
ID: script.ID,
|
|
||||||
Name: script.Name,
|
|
||||||
Hash: model.HashFormat(uint64(script.Hash)),
|
|
||||||
Source: script.Source,
|
|
||||||
ResourceType: int32(script.ResourceType),
|
|
||||||
ResourceID: script.ResourceID,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateScript implements updateScript operation.
|
|
||||||
//
|
|
||||||
// Update the specified script by ID.
|
|
||||||
//
|
|
||||||
// PATCH /scripts/{ScriptID}
|
|
||||||
func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, params api.UpdateScriptParams) error {
|
|
||||||
err := CheckHasRoleScriptWrite(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := service.NewScriptFilter()
|
|
||||||
if name, name_ok := req.Name.Get(); name_ok{
|
|
||||||
filter.SetName(name)
|
|
||||||
}
|
|
||||||
if source, source_ok := req.Source.Get(); source_ok{
|
|
||||||
filter.SetSource(source)
|
|
||||||
filter.SetHash(int64(model.HashSource(source)))
|
|
||||||
}
|
|
||||||
if resource_type, resource_type_ok := req.ResourceType.Get(); resource_type_ok{
|
|
||||||
filter.SetResourceType(resource_type)
|
|
||||||
}
|
|
||||||
if resource_id, resource_id_ok := req.ResourceID.Get(); resource_id_ok{
|
|
||||||
filter.SetResourceID(resource_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc.inner.UpdateScript(ctx, req.ID, filter)
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package web_api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/api"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/roblox"
|
|
||||||
"git.itzana.me/strafesnet/maps-service/pkg/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrPermissionDenied caller does not have the required role
|
|
||||||
ErrPermissionDenied = errors.New("Permission denied")
|
|
||||||
// ErrUserInfo user info is missing for some reason
|
|
||||||
ErrUserInfo = errors.New("Missing user info")
|
|
||||||
ErrDelayReset = errors.New("Please give the validator at least 10 seconds to operate before attempting to reset the status")
|
|
||||||
ErrPermissionDeniedNotSubmitter = fmt.Errorf("%w: You must be the submitter to perform this action", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleSubmissionRelease = fmt.Errorf("%w: Need Role SubmissionRelease", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleMapfixUpload = fmt.Errorf("%w: Need Role MapfixUpload", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleMapfixReview = fmt.Errorf("%w: Need Role MapfixReview", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleSubmissionUpload = fmt.Errorf("%w: Need Role SubmissionUpload", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleSubmissionReview = fmt.Errorf("%w: Need Role SubmissionReview", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleMapDownload = fmt.Errorf("%w: Need Role MapDownload", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleScriptWrite = fmt.Errorf("%w: Need Role ScriptWrite", ErrPermissionDenied)
|
|
||||||
ErrPermissionDeniedNeedRoleMaptest = fmt.Errorf("%w: Need Role Maptest", ErrPermissionDenied)
|
|
||||||
ErrNegativeID = errors.New("A negative ID was provided")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
inner *service.Service
|
|
||||||
roblox roblox.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewService(
|
|
||||||
inner *service.Service,
|
|
||||||
roblox roblox.Client,
|
|
||||||
) Service {
|
|
||||||
return Service{
|
|
||||||
inner: inner,
|
|
||||||
roblox: roblox,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewError creates *ErrorStatusCode from error returned by handler.
|
|
||||||
//
|
|
||||||
// Used for common default response.
|
|
||||||
func (svc *Service) NewError(ctx context.Context, err error) *api.ErrorStatusCode {
|
|
||||||
status := 500
|
|
||||||
if errors.Is(err, datastore.ErrNotExist) {
|
|
||||||
status = 404
|
|
||||||
}
|
|
||||||
if errors.Is(err, ErrPermissionDenied) {
|
|
||||||
status = 403
|
|
||||||
}
|
|
||||||
if errors.Is(err, ErrUserInfo) {
|
|
||||||
status = 401
|
|
||||||
}
|
|
||||||
return &api.ErrorStatusCode{
|
|
||||||
StatusCode: status,
|
|
||||||
Response: api.Error{
|
|
||||||
Code: int64(status),
|
|
||||||
Message: err.Error(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,18 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "maps-validation"
|
name = "maps-validation"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-nats = "0.42.0"
|
submissions-api = { path = "api", features = ["internal"], default-features = false, registry = "strafesnet" }
|
||||||
|
async-nats = "0.40.0"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
rbx_asset = { version = "0.4.7", registry = "strafesnet" }
|
rbx_asset = { version = "0.3.3", registry = "strafesnet" }
|
||||||
rbx_binary = "1.0.0"
|
rbx_binary = { version = "0.7.4", registry = "strafesnet"}
|
||||||
rbx_dom_weak = "3.0.0"
|
rbx_dom_weak = { version = "2.9.0", registry = "strafesnet"}
|
||||||
rbx_reflection_database = "1.0.3"
|
rbx_reflection_database = { version = "0.2.12", registry = "strafesnet"}
|
||||||
rbx_xml = "1.0.0"
|
rbx_xml = { version = "0.13.3", registry = "strafesnet"}
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
serde_json = "1.0.133"
|
serde_json = "1.0.133"
|
||||||
siphasher = "1.0.1"
|
siphasher = "1.0.1"
|
||||||
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread", "signal"] }
|
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread", "signal"] }
|
||||||
heck = "0.5.0"
|
|
||||||
lazy-regex = "3.4.1"
|
|
||||||
rust-grpc = { version = "1.2.1", registry = "strafesnet" }
|
|
||||||
tonic = "0.13.1"
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Using the `rust-musl-builder` as base image, instead of
|
# Using the `rust-musl-builder` as base image, instead of
|
||||||
# the official Rust toolchain
|
# the official Rust toolchain
|
||||||
FROM registry.itzana.me/docker-proxy/clux/muslrust:1.86.0-stable AS chef
|
FROM docker.io/clux/muslrust:stable AS chef
|
||||||
USER root
|
USER root
|
||||||
RUN cargo install cargo-chef
|
RUN cargo install cargo-chef
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
@@ -17,7 +17,7 @@ RUN cargo chef cook --release --target x86_64-unknown-linux-musl --recipe-path r
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN cargo build --release --target x86_64-unknown-linux-musl --bin maps-validation
|
RUN cargo build --release --target x86_64-unknown-linux-musl --bin maps-validation
|
||||||
|
|
||||||
FROM registry.itzana.me/docker-proxy/alpine:3.21 AS runtime
|
FROM docker.io/alpine:latest AS runtime
|
||||||
RUN addgroup -S myuser && adduser -S myuser -G myuser
|
RUN addgroup -S myuser && adduser -S myuser -G myuser
|
||||||
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/maps-validation /usr/local/bin/
|
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/maps-validation /usr/local/bin/
|
||||||
USER myuser
|
USER myuser
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "submissions-api"
|
name = "submissions-api"
|
||||||
version = "0.8.2"
|
version = "0.6.1"
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
publish = ["strafesnet"]
|
publish = ["strafesnet"]
|
||||||
repository = "https://git.itzana.me/StrafesNET/maps-service"
|
repository = "https://git.itzana.me/StrafesNET/maps-service"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@@ -11,9 +11,13 @@ 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"
|
||||||
serde_repr = "0.1.19"
|
serde_repr = "0.1.19"
|
||||||
url = "2"
|
url = "2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["external"]
|
||||||
|
internal = []
|
||||||
|
external = []
|
||||||
|
|||||||
@@ -33,14 +33,15 @@ impl Context{
|
|||||||
self.client.get(url)
|
self.client.get(url)
|
||||||
.send().await
|
.send().await
|
||||||
}
|
}
|
||||||
|
#[cfg(feature="internal")]
|
||||||
|
pub async fn post_empty_body(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
|
||||||
|
self.client.post(url)
|
||||||
|
.send().await
|
||||||
|
}
|
||||||
pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into<reqwest::Body>)->Result<reqwest::Response,reqwest::Error>{
|
pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into<reqwest::Body>)->Result<reqwest::Response,reqwest::Error>{
|
||||||
self.client.post(url)
|
self.client.post(url)
|
||||||
.header("Content-Type","application/json")
|
.header("Content-Type","application/json")
|
||||||
.body(body)
|
.body(body)
|
||||||
.send().await
|
.send().await
|
||||||
}
|
}
|
||||||
pub async fn delete(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
|
|
||||||
self.client.delete(url)
|
|
||||||
.send().await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,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_scripts(&self,config:GetScriptsRequest<'_>)->Result<Vec<ScriptResponse>,Error>{
|
pub async fn get_scripts<'a>(&self,config:GetScriptsRequest<'a>)->Result<Vec<ScriptResponse>,Error>{
|
||||||
let url_raw=format!("{}/scripts",self.0.base_url);
|
let url_raw=format!("{}/scripts",self.0.base_url);
|
||||||
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
@@ -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(ResourceID(resource_id))=config.ResourceID{
|
if let Some(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>,ScriptSingleItemError>{
|
pub async fn get_script_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptResponse>,SingleItemError>{
|
||||||
let scripts=self.get_scripts(GetScriptsRequest{
|
let scripts=self.get_scripts(GetScriptsRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -57,11 +57,11 @@ 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(scripts.into_iter().map(|item|item.ID).collect()));
|
return Err(SingleItemError::DuplicateItems);
|
||||||
}
|
}
|
||||||
Ok(scripts.into_iter().next())
|
Ok(scripts.into_iter().next())
|
||||||
}
|
}
|
||||||
pub async fn create_script(&self,config:CreateScriptRequest<'_>)->Result<ScriptIDResponse,Error>{
|
pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result<ScriptIDResponse,Error>{
|
||||||
let url_raw=format!("{}/scripts",self.0.base_url);
|
let url_raw=format!("{}/scripts",self.0.base_url);
|
||||||
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
@@ -72,17 +72,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 delete_script(&self,config:GetScriptRequest)->Result<(),Error>{
|
pub async fn get_script_policies<'a>(&self,config:GetScriptPoliciesRequest<'a>)->Result<Vec<ScriptPolicyResponse>,Error>{
|
||||||
let url_raw=format!("{}/scripts/{}",self.0.base_url,config.ScriptID.0);
|
|
||||||
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
|
||||||
|
|
||||||
response_ok(
|
|
||||||
self.0.delete(url).await.map_err(Error::Reqwest)?
|
|
||||||
).await.map_err(Error::Response)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub async fn get_script_policies(&self,config:GetScriptPoliciesRequest<'_>)->Result<Vec<ScriptPolicyResponse>,Error>{
|
|
||||||
let url_raw=format!("{}/script-policy",self.0.base_url);
|
let url_raw=format!("{}/script-policy",self.0.base_url);
|
||||||
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
@@ -106,7 +96,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>,ScriptPolicySingleItemError>{
|
pub async fn get_script_policy_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptPolicyResponse>,SingleItemError>{
|
||||||
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
||||||
Page:1,
|
Page:1,
|
||||||
Limit:2,
|
Limit:2,
|
||||||
@@ -115,7 +105,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(policies.into_iter().map(|item|item.ID).collect()));
|
return Err(SingleItemError::DuplicateItems);
|
||||||
}
|
}
|
||||||
Ok(policies.into_iter().next())
|
Ok(policies.into_iter().next())
|
||||||
}
|
}
|
||||||
@@ -140,94 +130,6 @@ impl Context{
|
|||||||
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
).await.map_err(Error::Response)?;
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub async fn delete_script_policy(&self,config:GetScriptPolicyRequest)->Result<(),Error>{
|
|
||||||
let url_raw=format!("{}/script-policy/{}",self.0.base_url,config.ScriptPolicyID.0);
|
|
||||||
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
|
||||||
|
|
||||||
response_ok(
|
|
||||||
self.0.delete(url).await.map_err(Error::Reqwest)?
|
|
||||||
).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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
201
validation/api/src/internal.rs
Normal file
201
validation/api/src/internal.rs
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Context(crate::context::Context);
|
||||||
|
|
||||||
|
// conditionally include specified query pairs
|
||||||
|
macro_rules! query_pairs{
|
||||||
|
($url:expr,)=>{
|
||||||
|
$url
|
||||||
|
};
|
||||||
|
($url:expr,$(($param:expr,$value:expr))+)=>{
|
||||||
|
{
|
||||||
|
let mut url=$url;
|
||||||
|
url.query_pairs_mut()
|
||||||
|
$(.append_pair($param,$value))*;
|
||||||
|
url
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// there are lots of action endpoints and they all follow the same pattern
|
||||||
|
macro_rules! action{
|
||||||
|
($system:expr,$fname:ident,$config:ident,$config_type:ident,$action:expr,$config_submission_id:expr,$(($param:expr,$value:expr))*)=>{
|
||||||
|
pub async fn $fname(&self,$config:$config_type)->Result<(),Error>{
|
||||||
|
let url_raw=format!(concat!("{}/",$system,"/{}/status/",$action),self.0.base_url,$config_submission_id);
|
||||||
|
let url=query_pairs!(reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?,$(($param,$value))*);
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
impl Context{
|
||||||
|
pub fn new(base_url:String)->reqwest::Result<Self>{
|
||||||
|
Ok(Self(crate::context::Context::new(base_url,None)?))
|
||||||
|
}
|
||||||
|
pub async fn get_script(&self,config:GetScriptRequest)->Result<ScriptResponse,Error>{
|
||||||
|
let url_raw=format!("{}/scripts/{}",self.0.base_url,config.ScriptID.0);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.get(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn get_scripts<'a>(&self,config:GetScriptsRequest<'a>)->Result<Vec<ScriptResponse>,Error>{
|
||||||
|
let url_raw=format!("{}/scripts",self.0.base_url);
|
||||||
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut query_pairs=url.query_pairs_mut();
|
||||||
|
query_pairs.append_pair("Page",config.Page.to_string().as_str());
|
||||||
|
query_pairs.append_pair("Limit",config.Limit.to_string().as_str());
|
||||||
|
if let Some(name)=config.Name{
|
||||||
|
query_pairs.append_pair("Name",name);
|
||||||
|
}
|
||||||
|
if let Some(hash)=config.Hash{
|
||||||
|
query_pairs.append_pair("Hash",hash);
|
||||||
|
}
|
||||||
|
if let Some(source)=config.Source{
|
||||||
|
query_pairs.append_pair("Source",source);
|
||||||
|
}
|
||||||
|
if let Some(resource_type)=config.ResourceType{
|
||||||
|
query_pairs.append_pair("ResourceType",(resource_type as i32).to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(resource_id)=config.ResourceID{
|
||||||
|
query_pairs.append_pair("ResourceID",resource_id.to_string().as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.get(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn get_script_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptResponse>,SingleItemError>{
|
||||||
|
let scripts=self.get_scripts(GetScriptsRequest{
|
||||||
|
Page:1,
|
||||||
|
Limit:2,
|
||||||
|
Hash:Some(config.hash),
|
||||||
|
Name:None,
|
||||||
|
Source:None,
|
||||||
|
ResourceType:None,
|
||||||
|
ResourceID:None,
|
||||||
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
|
if 1<scripts.len(){
|
||||||
|
return Err(SingleItemError::DuplicateItems);
|
||||||
|
}
|
||||||
|
Ok(scripts.into_iter().next())
|
||||||
|
}
|
||||||
|
pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result<ScriptIDResponse,Error>{
|
||||||
|
let url_raw=format!("{}/scripts",self.0.base_url);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn get_script_policies<'a>(&self,config:GetScriptPoliciesRequest<'a>)->Result<Vec<ScriptPolicyResponse>,Error>{
|
||||||
|
let url_raw=format!("{}/script-policy",self.0.base_url);
|
||||||
|
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut query_pairs=url.query_pairs_mut();
|
||||||
|
query_pairs.append_pair("Page",config.Page.to_string().as_str());
|
||||||
|
query_pairs.append_pair("Limit",config.Limit.to_string().as_str());
|
||||||
|
if let Some(hash)=config.FromScriptHash{
|
||||||
|
query_pairs.append_pair("FromScriptHash",hash);
|
||||||
|
}
|
||||||
|
if let Some(script_id)=config.ToScriptID{
|
||||||
|
query_pairs.append_pair("ToScriptID",script_id.0.to_string().as_str());
|
||||||
|
}
|
||||||
|
if let Some(policy)=config.Policy{
|
||||||
|
query_pairs.append_pair("Policy",(policy as i32).to_string().as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.get(url).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn get_script_policy_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptPolicyResponse>,SingleItemError>{
|
||||||
|
let policies=self.get_script_policies(GetScriptPoliciesRequest{
|
||||||
|
Page:1,
|
||||||
|
Limit:2,
|
||||||
|
FromScriptHash:Some(config.hash),
|
||||||
|
ToScriptID:None,
|
||||||
|
Policy:None,
|
||||||
|
}).await.map_err(SingleItemError::Other)?;
|
||||||
|
if 1<policies.len(){
|
||||||
|
return Err(SingleItemError::DuplicateItems);
|
||||||
|
}
|
||||||
|
Ok(policies.into_iter().next())
|
||||||
|
}
|
||||||
|
pub async fn create_script_policy(&self,config:CreateScriptPolicyRequest)->Result<ScriptPolicyIDResponse,Error>{
|
||||||
|
let url_raw=format!("{}/script-policy",self.0.base_url);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
pub async fn create_submission<'a>(&self,config:CreateSubmissionRequest<'a>)->Result<SubmissionIDResponse,Error>{
|
||||||
|
let url_raw=format!("{}/submissions",self.0.base_url);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
// simple submission endpoints
|
||||||
|
action!("submissions",action_submission_validated,config,SubmissionID,"validator-validated",config.0,);
|
||||||
|
action!("submissions",update_submission_validated_model,config,UpdateSubmissionModelRequest,"validated-model",config.SubmissionID,
|
||||||
|
("ValidatedModelID",config.ModelID.to_string().as_str())
|
||||||
|
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
|
);
|
||||||
|
action!("submissions",action_submission_uploaded,config,ActionSubmissionUploadedRequest,"validator-uploaded",config.SubmissionID,
|
||||||
|
("UploadedAssetID",config.UploadedAssetID.to_string().as_str())
|
||||||
|
);
|
||||||
|
action!("submissions",action_submission_accepted,config,ActionSubmissionAcceptedRequest,"validator-failed",config.SubmissionID,
|
||||||
|
("StatusMessage",config.StatusMessage.as_str())
|
||||||
|
);
|
||||||
|
pub async fn create_mapfix<'a>(&self,config:CreateMapfixRequest<'a>)->Result<MapfixIDResponse,Error>{
|
||||||
|
let url_raw=format!("{}/mapfixes",self.0.base_url);
|
||||||
|
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
|
||||||
|
|
||||||
|
let body=serde_json::to_string(&config).map_err(Error::JSON)?;
|
||||||
|
|
||||||
|
response_ok(
|
||||||
|
self.0.post(url,body).await.map_err(Error::Reqwest)?
|
||||||
|
).await.map_err(Error::Response)?
|
||||||
|
.json().await.map_err(Error::ReqwestJson)
|
||||||
|
}
|
||||||
|
// simple mapfixes endpoints
|
||||||
|
action!("mapfixes",action_mapfix_validated,config,MapfixID,"validator-validated",config.0,);
|
||||||
|
action!("mapfixes",update_mapfix_validated_model,config,UpdateMapfixModelRequest,"validated-model",config.MapfixID,
|
||||||
|
("ValidatedModelID",config.ModelID.to_string().as_str())
|
||||||
|
("ValidatedModelVersion",config.ModelVersion.to_string().as_str())
|
||||||
|
);
|
||||||
|
action!("mapfixes",action_mapfix_uploaded,config,ActionMapfixUploadedRequest,"validator-uploaded",config.MapfixID,);
|
||||||
|
action!("mapfixes",action_mapfix_accepted,config,ActionMapfixAcceptedRequest,"validator-failed",config.MapfixID,
|
||||||
|
("StatusMessage",config.StatusMessage.as_str())
|
||||||
|
);
|
||||||
|
// simple operation endpoint
|
||||||
|
action!("operations",action_operation_failed,config,ActionOperationFailedRequest,"operation-failed",config.OperationID,
|
||||||
|
("StatusMessage",config.StatusMessage.as_str())
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,6 +2,11 @@ mod context;
|
|||||||
pub use context::Cookie;
|
pub use context::Cookie;
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
#[cfg(feature="internal")]
|
||||||
|
pub mod internal;
|
||||||
|
|
||||||
|
#[cfg(feature="external")]
|
||||||
pub mod external;
|
pub mod external;
|
||||||
|
|
||||||
//lazy reexports
|
//lazy reexports
|
||||||
|
|||||||
@@ -14,25 +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<Items>{
|
pub enum SingleItemError{
|
||||||
DuplicateItems(Items),
|
DuplicateItems,
|
||||||
Other(Error),
|
Other(Error),
|
||||||
}
|
}
|
||||||
impl<Items> std::fmt::Display for SingleItemError<Items>
|
impl std::fmt::Display for SingleItemError{
|
||||||
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<Items> std::error::Error for SingleItemError<Items> where Items:std::fmt::Debug{}
|
impl std::error::Error for SingleItemError{}
|
||||||
pub type ScriptSingleItemError=SingleItemError<Vec<ScriptID>>;
|
|
||||||
pub type ScriptPolicySingleItemError=SingleItemError<Vec<ScriptPolicyID>>;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UrlAndBody{
|
pub struct StatusCodeWithUrlAndBody{
|
||||||
|
pub status_code:reqwest::StatusCode,
|
||||||
pub url:url::Url,
|
pub url:url::Url,
|
||||||
pub body:String,
|
pub body:String,
|
||||||
}
|
}
|
||||||
@@ -40,10 +36,7 @@ pub struct UrlAndBody{
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ResponseError{
|
pub enum ResponseError{
|
||||||
Reqwest(reqwest::Error),
|
Reqwest(reqwest::Error),
|
||||||
Details{
|
StatusCodeWithUrlAndBody(StatusCodeWithUrlAndBody),
|
||||||
status_code:reqwest::StatusCode,
|
|
||||||
url_and_body:Box<UrlAndBody>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for ResponseError{
|
impl std::fmt::Display for ResponseError{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
@@ -60,34 +53,26 @@ pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,R
|
|||||||
let url=response.url().to_owned();
|
let url=response.url().to_owned();
|
||||||
let bytes=response.bytes().await.map_err(ResponseError::Reqwest)?;
|
let bytes=response.bytes().await.map_err(ResponseError::Reqwest)?;
|
||||||
let body=String::from_utf8_lossy(&bytes).to_string();
|
let body=String::from_utf8_lossy(&bytes).to_string();
|
||||||
Err(ResponseError::Details{
|
Err(ResponseError::StatusCodeWithUrlAndBody(StatusCodeWithUrlAndBody{
|
||||||
status_code,
|
status_code,
|
||||||
url_and_body:Box::new(UrlAndBody{url,body})
|
url,
|
||||||
})
|
body,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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:OperationID,
|
pub OperationID:i32,
|
||||||
pub AssetOwner:i64,
|
pub AssetOwner:i64,
|
||||||
pub DisplayName:&'a str,
|
pub DisplayName:&'a str,
|
||||||
pub Creator:&'a str,
|
pub Creator:&'a str,
|
||||||
pub GameID:GameID,
|
pub GameID:i32,
|
||||||
pub AssetID:u64,
|
pub AssetID:u64,
|
||||||
pub AssetVersion:u64,
|
pub AssetVersion:u64,
|
||||||
pub TargetAssetID:u64,
|
pub TargetAssetID:u64,
|
||||||
pub Description:&'a str,
|
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
@@ -98,15 +83,13 @@ 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:OperationID,
|
pub OperationID:i32,
|
||||||
pub AssetOwner:i64,
|
pub AssetOwner:i64,
|
||||||
pub DisplayName:&'a str,
|
pub DisplayName:&'a str,
|
||||||
pub Creator:&'a str,
|
pub Creator:&'a str,
|
||||||
pub GameID:GameID,
|
pub GameID:i32,
|
||||||
pub AssetID:u64,
|
pub AssetID:u64,
|
||||||
pub AssetVersion:u64,
|
pub AssetVersion:u64,
|
||||||
pub Status:u32,
|
|
||||||
pub Roles:u32,
|
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
@@ -114,9 +97,9 @@ pub struct SubmissionIDResponse{
|
|||||||
pub SubmissionID:SubmissionID,
|
pub SubmissionID:SubmissionID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
#[derive(Clone,Copy,Debug,PartialEq,Eq,serde::Serialize,serde::Deserialize)]
|
||||||
pub struct ScriptID(pub(crate)i64);
|
pub struct ScriptID(pub(crate)i64);
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
#[derive(Clone,Copy,Debug,serde::Serialize,serde::Deserialize)]
|
||||||
pub struct ScriptPolicyID(pub(crate)i64);
|
pub struct ScriptPolicyID(pub(crate)i64);
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,PartialEq,Eq,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
|
#[derive(Clone,Copy,Debug,PartialEq,Eq,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
|
||||||
@@ -145,7 +128,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<ResourceID>,
|
pub ResourceID:Option<i64>,
|
||||||
}
|
}
|
||||||
#[derive(Clone,Copy,Debug)]
|
#[derive(Clone,Copy,Debug)]
|
||||||
pub struct HashRequest<'a>{
|
pub struct HashRequest<'a>{
|
||||||
@@ -159,7 +142,7 @@ pub struct ScriptResponse{
|
|||||||
pub Hash:String,
|
pub Hash:String,
|
||||||
pub Source:String,
|
pub Source:String,
|
||||||
pub ResourceType:ResourceType,
|
pub ResourceType:ResourceType,
|
||||||
pub ResourceID:ResourceID,
|
pub ResourceID:i64,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
@@ -168,7 +151,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<ResourceID>,
|
pub ResourceID:Option<i64>,
|
||||||
}
|
}
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Deserialize)]
|
#[derive(Clone,Debug,serde::Deserialize)]
|
||||||
@@ -186,10 +169,6 @@ pub enum Policy{
|
|||||||
Replace=4,
|
Replace=4,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
pub struct GetScriptPolicyRequest{
|
|
||||||
pub ScriptPolicyID:ScriptPolicyID,
|
|
||||||
}
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug,serde::Serialize)]
|
#[derive(Clone,Debug,serde::Serialize)]
|
||||||
pub struct GetScriptPoliciesRequest<'a>{
|
pub struct GetScriptPoliciesRequest<'a>{
|
||||||
@@ -238,243 +217,55 @@ pub struct UpdateScriptPolicyRequest{
|
|||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct UpdateSubmissionModelRequest{
|
pub struct UpdateSubmissionModelRequest{
|
||||||
pub SubmissionID:SubmissionID,
|
pub SubmissionID:i64,
|
||||||
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)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct ActionSubmissionSubmittedRequest{
|
|
||||||
pub SubmissionID:SubmissionID,
|
|
||||||
pub ModelVersion:u64,
|
|
||||||
pub DisplayName:String,
|
|
||||||
pub Creator:String,
|
|
||||||
pub GameID:GameID,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct ActionSubmissionRequestChangesRequest{
|
|
||||||
pub SubmissionID:SubmissionID,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionSubmissionUploadedRequest{
|
pub struct ActionSubmissionUploadedRequest{
|
||||||
pub SubmissionID:SubmissionID,
|
pub SubmissionID:i64,
|
||||||
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:SubmissionID,
|
pub SubmissionID:i64,
|
||||||
|
pub StatusMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[derive(Clone,Copy,Debug,serde::Deserialize)]
|
||||||
#[derive(Clone,Debug)]
|
pub struct SubmissionID(pub i64);
|
||||||
pub struct CreateSubmissionAuditErrorRequest{
|
|
||||||
pub SubmissionID:SubmissionID,
|
|
||||||
pub ErrorMessage:String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct CreateSubmissionAuditCheckListRequest<'a>{
|
|
||||||
pub SubmissionID:SubmissionID,
|
|
||||||
pub CheckList:&'a [Check],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,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:MapfixID,
|
pub MapfixID:i64,
|
||||||
pub ModelID:u64,
|
pub ModelID:u64,
|
||||||
pub ModelVersion:u64,
|
pub ModelVersion:u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct ActionMapfixSubmittedRequest{
|
|
||||||
pub MapfixID:MapfixID,
|
|
||||||
pub ModelVersion:u64,
|
|
||||||
pub DisplayName:String,
|
|
||||||
pub Creator:String,
|
|
||||||
pub GameID:GameID,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct ActionMapfixRequestChangesRequest{
|
|
||||||
pub MapfixID:MapfixID,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixUploadedRequest{
|
pub struct ActionMapfixUploadedRequest{
|
||||||
pub MapfixID:MapfixID,
|
pub MapfixID:i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[allow(nonstandard_style)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct ActionMapfixAcceptedRequest{
|
pub struct ActionMapfixAcceptedRequest{
|
||||||
pub MapfixID:MapfixID,
|
pub MapfixID:i64,
|
||||||
|
pub StatusMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
#[derive(Clone,Copy,Debug,serde::Deserialize)]
|
||||||
#[derive(Clone,Debug)]
|
pub struct MapfixID(pub i64);
|
||||||
pub struct CreateMapfixAuditErrorRequest{
|
|
||||||
pub MapfixID:MapfixID,
|
|
||||||
pub ErrorMessage:String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
#[derive(Clone,Debug)]
|
|
||||||
pub struct CreateMapfixAuditCheckListRequest<'a>{
|
|
||||||
pub MapfixID:MapfixID,
|
|
||||||
pub CheckList:&'a [Check],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,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:OperationID,
|
pub OperationID:i32,
|
||||||
pub StatusMessage:String,
|
pub StatusMessage:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,serde::Serialize,serde::Deserialize)]
|
|
||||||
pub struct OperationID(pub(crate)i64);
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,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,900 +0,0 @@
|
|||||||
use std::collections::{HashSet,HashMap};
|
|
||||||
use crate::download::download_asset_version;
|
|
||||||
use crate::rbx_util::{get_mapinfo,get_root_instance,read_dom,ReadDomError,GameID,ParseGameIDError,MapInfo,GetRootInstanceError,StringValueError};
|
|
||||||
|
|
||||||
use heck::{ToSnakeCase,ToTitleCase};
|
|
||||||
use rbx_dom_weak::Instance;
|
|
||||||
use rust_grpc::validator::Check;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error{
|
|
||||||
ModelInfoDownload(rbx_asset::cloud::GetError),
|
|
||||||
CreatorTypeMustBeUser,
|
|
||||||
Download(crate::download::Error),
|
|
||||||
ModelFileDecode(ReadDomError),
|
|
||||||
GetRootInstance(GetRootInstanceError),
|
|
||||||
IntoMapInfoOwned(IntoMapInfoOwnedError),
|
|
||||||
ToJsonValue(serde_json::Error),
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for Error{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"{self:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::error::Error for Error{}
|
|
||||||
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
pub struct CheckRequest{
|
|
||||||
ModelID:u64,
|
|
||||||
SkipChecks:bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<crate::nats_types::CheckMapfixRequest> for CheckRequest{
|
|
||||||
fn from(value:crate::nats_types::CheckMapfixRequest)->Self{
|
|
||||||
Self{
|
|
||||||
ModelID:value.ModelID,
|
|
||||||
SkipChecks:value.SkipChecks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<crate::nats_types::CheckSubmissionRequest> for CheckRequest{
|
|
||||||
fn from(value:crate::nats_types::CheckSubmissionRequest)->Self{
|
|
||||||
Self{
|
|
||||||
ModelID:value.ModelID,
|
|
||||||
SkipChecks:value.SkipChecks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
|
|
||||||
struct ModeID(u64);
|
|
||||||
impl ModeID{
|
|
||||||
const MAIN:Self=Self(0);
|
|
||||||
const BONUS:Self=Self(1);
|
|
||||||
}
|
|
||||||
enum Zone{
|
|
||||||
Start,
|
|
||||||
Finish,
|
|
||||||
Anticheat,
|
|
||||||
}
|
|
||||||
struct ModeElement{
|
|
||||||
zone:Zone,
|
|
||||||
mode_id:ModeID,
|
|
||||||
}
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub enum IDParseError{
|
|
||||||
NoCaptures,
|
|
||||||
ParseInt(core::num::ParseIntError),
|
|
||||||
}
|
|
||||||
// Parse a Zone from a part name
|
|
||||||
impl std::str::FromStr for ModeElement{
|
|
||||||
type Err=IDParseError;
|
|
||||||
fn from_str(s:&str)->Result<Self,Self::Err>{
|
|
||||||
match s{
|
|
||||||
"MapStart"=>Ok(Self{zone:Zone::Start,mode_id:ModeID::MAIN}),
|
|
||||||
"MapFinish"=>Ok(Self{zone:Zone::Finish,mode_id:ModeID::MAIN}),
|
|
||||||
"MapAnticheat"=>Ok(Self{zone:Zone::Anticheat,mode_id:ModeID::MAIN}),
|
|
||||||
"BonusStart"=>Ok(Self{zone:Zone::Start,mode_id:ModeID::BONUS}),
|
|
||||||
"BonusFinish"=>Ok(Self{zone:Zone::Finish,mode_id:ModeID::BONUS}),
|
|
||||||
"BonusAnticheat"=>Ok(Self{zone:Zone::Anticheat,mode_id:ModeID::BONUS}),
|
|
||||||
other=>{
|
|
||||||
let everything_pattern=lazy_regex::lazy_regex!(r"^Bonus(\d+)Start$|^BonusStart(\d+)$|^Bonus(\d+)Finish$|^BonusFinish(\d+)$|^Bonus(\d+)Anticheat$|^BonusAnticheat(\d+)$");
|
|
||||||
if let Some(captures)=everything_pattern.captures(other){
|
|
||||||
if let Some(mode_id)=captures.get(1).or(captures.get(2)){
|
|
||||||
return Ok(Self{
|
|
||||||
zone:Zone::Start,
|
|
||||||
mode_id:ModeID(mode_id.as_str().parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if let Some(mode_id)=captures.get(3).or(captures.get(4)){
|
|
||||||
return Ok(Self{
|
|
||||||
zone:Zone::Finish,
|
|
||||||
mode_id:ModeID(mode_id.as_str().parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if let Some(mode_id)=captures.get(5).or(captures.get(6)){
|
|
||||||
return Ok(Self{
|
|
||||||
zone:Zone::Anticheat,
|
|
||||||
mode_id:ModeID(mode_id.as_str().parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(IDParseError::NoCaptures)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for ModeElement{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
match self{
|
|
||||||
ModeElement{zone:Zone::Start,mode_id:ModeID::MAIN}=>write!(f,"MapStart"),
|
|
||||||
ModeElement{zone:Zone::Start,mode_id:ModeID::BONUS}=>write!(f,"BonusStart"),
|
|
||||||
ModeElement{zone:Zone::Start,mode_id:ModeID(mode_id)}=>write!(f,"Bonus{mode_id}Start"),
|
|
||||||
ModeElement{zone:Zone::Finish,mode_id:ModeID::MAIN}=>write!(f,"MapFinish"),
|
|
||||||
ModeElement{zone:Zone::Finish,mode_id:ModeID::BONUS}=>write!(f,"BonusFinish"),
|
|
||||||
ModeElement{zone:Zone::Finish,mode_id:ModeID(mode_id)}=>write!(f,"Bonus{mode_id}Finish"),
|
|
||||||
ModeElement{zone:Zone::Anticheat,mode_id:ModeID::MAIN}=>write!(f,"MapAnticheat"),
|
|
||||||
ModeElement{zone:Zone::Anticheat,mode_id:ModeID::BONUS}=>write!(f,"BonusAnticheat"),
|
|
||||||
ModeElement{zone:Zone::Anticheat,mode_id:ModeID(mode_id)}=>write!(f,"Bonus{mode_id}Anticheat"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
|
|
||||||
struct StageID(u64);
|
|
||||||
impl StageID{
|
|
||||||
const FIRST:Self=Self(1);
|
|
||||||
}
|
|
||||||
enum StageElementBehaviour{
|
|
||||||
Teleport,
|
|
||||||
Spawn,
|
|
||||||
}
|
|
||||||
struct StageElement{
|
|
||||||
stage_id:StageID,
|
|
||||||
behaviour:StageElementBehaviour,
|
|
||||||
}
|
|
||||||
// Parse a SpawnTeleport from a part name
|
|
||||||
impl std::str::FromStr for StageElement{
|
|
||||||
type Err=IDParseError;
|
|
||||||
fn from_str(s:&str)->Result<Self,Self::Err>{
|
|
||||||
// Trigger ForceTrigger Teleport ForceTeleport SpawnAt ForceSpawnAt
|
|
||||||
let bonus_start_pattern=lazy_regex::lazy_regex!(r"^(?:Force)?(Teleport|SpawnAt|Trigger)(\d+)$");
|
|
||||||
if let Some(captures)=bonus_start_pattern.captures(s){
|
|
||||||
return Ok(StageElement{
|
|
||||||
behaviour:StageElementBehaviour::Teleport,
|
|
||||||
stage_id:StageID(captures[1].parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Spawn
|
|
||||||
let bonus_finish_pattern=lazy_regex::lazy_regex!(r"^Spawn(\d+)$");
|
|
||||||
if let Some(captures)=bonus_finish_pattern.captures(s){
|
|
||||||
return Ok(StageElement{
|
|
||||||
behaviour:StageElementBehaviour::Spawn,
|
|
||||||
stage_id:StageID(captures[1].parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(IDParseError::NoCaptures)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for StageElement{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
match self{
|
|
||||||
StageElement{behaviour:StageElementBehaviour::Spawn,stage_id:StageID(stage_id)}=>write!(f,"Spawn{stage_id}"),
|
|
||||||
StageElement{behaviour:StageElementBehaviour::Teleport,stage_id:StageID(stage_id)}=>write!(f,"Teleport{stage_id}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
|
|
||||||
struct WormholeID(u64);
|
|
||||||
enum WormholeBehaviour{
|
|
||||||
In,
|
|
||||||
Out,
|
|
||||||
}
|
|
||||||
struct WormholeElement{
|
|
||||||
behaviour:WormholeBehaviour,
|
|
||||||
wormhole_id:WormholeID,
|
|
||||||
}
|
|
||||||
// Parse a Wormhole from a part name
|
|
||||||
impl std::str::FromStr for WormholeElement{
|
|
||||||
type Err=IDParseError;
|
|
||||||
fn from_str(s:&str)->Result<Self,Self::Err>{
|
|
||||||
let bonus_start_pattern=lazy_regex::lazy_regex!(r"^WormholeIn(\d+)$");
|
|
||||||
if let Some(captures)=bonus_start_pattern.captures(s){
|
|
||||||
return Ok(Self{
|
|
||||||
behaviour:WormholeBehaviour::In,
|
|
||||||
wormhole_id:WormholeID(captures[1].parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let bonus_finish_pattern=lazy_regex::lazy_regex!(r"^WormholeOut(\d+)$");
|
|
||||||
if let Some(captures)=bonus_finish_pattern.captures(s){
|
|
||||||
return Ok(Self{
|
|
||||||
behaviour:WormholeBehaviour::Out,
|
|
||||||
wormhole_id:WormholeID(captures[1].parse().map_err(IDParseError::ParseInt)?),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(IDParseError::NoCaptures)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::fmt::Display for WormholeElement{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
match self{
|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id:WormholeID(wormhole_id)}=>write!(f,"WormholeIn{wormhole_id}"),
|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id:WormholeID(wormhole_id)}=>write!(f,"WormholeOut{wormhole_id}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Count various map elements
|
|
||||||
#[derive(Default)]
|
|
||||||
struct Counts<'a>{
|
|
||||||
mode_start_counts:HashMap<ModeID,Vec<&'a Instance>>,
|
|
||||||
mode_finish_counts:HashMap<ModeID,Vec<&'a Instance>>,
|
|
||||||
mode_anticheat_counts:HashMap<ModeID,Vec<&'a Instance>>,
|
|
||||||
teleport_counts:HashMap<StageID,Vec<&'a Instance>>,
|
|
||||||
spawn_counts:HashMap<StageID,u64>,
|
|
||||||
wormhole_in_counts:HashMap<WormholeID,u64>,
|
|
||||||
wormhole_out_counts:HashMap<WormholeID,u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ModelInfo<'a>{
|
|
||||||
model_class:&'a str,
|
|
||||||
model_name:&'a str,
|
|
||||||
map_info:MapInfo<'a>,
|
|
||||||
counts:Counts<'a>,
|
|
||||||
unanchored_parts:Vec<&'a Instance>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_model_info<'a>(dom:&'a rbx_dom_weak::WeakDom,model_instance:&'a rbx_dom_weak::Instance)->ModelInfo<'a>{
|
|
||||||
// extract model info
|
|
||||||
let map_info=get_mapinfo(dom,model_instance);
|
|
||||||
|
|
||||||
// count objects (default count is 0)
|
|
||||||
let mut counts=Counts::default();
|
|
||||||
|
|
||||||
// locate unanchored parts
|
|
||||||
let mut unanchored_parts=Vec::new();
|
|
||||||
let anchored_ustr=rbx_dom_weak::ustr("Anchored");
|
|
||||||
|
|
||||||
let db=rbx_reflection_database::get();
|
|
||||||
let base_part=&db.classes["BasePart"];
|
|
||||||
let base_parts=dom.descendants_of(model_instance.referent()).filter(|&instance|
|
|
||||||
db.classes.get(instance.class.as_str()).is_some_and(|class|
|
|
||||||
db.has_superclass(class,base_part)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
for instance in base_parts{
|
|
||||||
// Zones
|
|
||||||
match instance.name.parse(){
|
|
||||||
Ok(ModeElement{zone:Zone::Start,mode_id})=>counts.mode_start_counts.entry(mode_id).or_default().push(instance),
|
|
||||||
Ok(ModeElement{zone:Zone::Finish,mode_id})=>counts.mode_finish_counts.entry(mode_id).or_default().push(instance),
|
|
||||||
Ok(ModeElement{zone:Zone::Anticheat,mode_id})=>counts.mode_anticheat_counts.entry(mode_id).or_default().push(instance),
|
|
||||||
Err(_)=>(),
|
|
||||||
}
|
|
||||||
// Spawns & Teleports
|
|
||||||
match instance.name.parse(){
|
|
||||||
Ok(StageElement{behaviour:StageElementBehaviour::Teleport,stage_id})=>counts.teleport_counts.entry(stage_id).or_default().push(instance),
|
|
||||||
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(_)=>(),
|
|
||||||
}
|
|
||||||
// Unanchored parts
|
|
||||||
if let Some(rbx_dom_weak::types::Variant::Bool(false))=instance.properties.get(&anchored_ustr){
|
|
||||||
unanchored_parts.push(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelInfo{
|
|
||||||
model_class:model_instance.class.as_str(),
|
|
||||||
model_name:model_instance.name.as_str(),
|
|
||||||
map_info,
|
|
||||||
counts,
|
|
||||||
unanchored_parts,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if an observed string matches an expected string
|
|
||||||
pub struct StringCheck<'a,T,Str>(Result<T,StringCheckContext<'a,Str>>);
|
|
||||||
pub struct StringCheckContext<'a,Str>{
|
|
||||||
observed:&'a str,
|
|
||||||
expected:Str,
|
|
||||||
}
|
|
||||||
impl<'a,Str> StringCheckContext<'a,Str>
|
|
||||||
where
|
|
||||||
&'a str:PartialEq<Str>,
|
|
||||||
{
|
|
||||||
/// Compute the StringCheck, passing through the provided value on success.
|
|
||||||
fn check<T>(self,value:T)->StringCheck<'a,T,Str>{
|
|
||||||
if self.observed==self.expected{
|
|
||||||
StringCheck(Ok(value))
|
|
||||||
}else{
|
|
||||||
StringCheck(Err(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<Str:std::fmt::Display> std::fmt::Display for StringCheckContext<'_,Str>{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"expected: {}, observed: {}",self.expected,self.observed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if a string is empty
|
|
||||||
pub struct StringEmpty;
|
|
||||||
impl std::fmt::Display for StringEmpty{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"Empty string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn check_empty(value:&str)->Result<&str,StringEmpty>{
|
|
||||||
(!value.is_empty()).then_some(value).ok_or(StringEmpty)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for duplicate objects
|
|
||||||
pub struct DuplicateCheckContext<ID,T>(HashMap<ID,T>);
|
|
||||||
pub struct DuplicateCheck<ID,T>(Result<(),DuplicateCheckContext<ID,T>>);
|
|
||||||
impl<ID,T> DuplicateCheckContext<ID,T>{
|
|
||||||
/// Compute the DuplicateCheck using the contents predicate.
|
|
||||||
fn check(self,f:impl Fn(&T)->bool)->DuplicateCheck<ID,T>{
|
|
||||||
let Self(mut set)=self;
|
|
||||||
// remove correct entries
|
|
||||||
set.retain(|_,c|f(c));
|
|
||||||
// if any entries remain, they are incorrect
|
|
||||||
if set.is_empty(){
|
|
||||||
DuplicateCheck(Ok(()))
|
|
||||||
}else{
|
|
||||||
DuplicateCheck(Err(Self(set)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that there are no items which do not have a matching item in a reference set
|
|
||||||
pub struct SetDifferenceCheckContextAllowNone<ID,T>{
|
|
||||||
extra:HashMap<ID,T>,
|
|
||||||
}
|
|
||||||
// Check that there is at least one matching item for each item in a reference set, and no extra items
|
|
||||||
pub struct SetDifferenceCheckContextAtLeastOne<ID,T>{
|
|
||||||
extra:HashMap<ID,T>,
|
|
||||||
missing:HashSet<ID>,
|
|
||||||
}
|
|
||||||
pub struct SetDifferenceCheck<Context>(Result<(),Context>);
|
|
||||||
impl<ID,T> SetDifferenceCheckContextAllowNone<ID,T>{
|
|
||||||
fn new(initial_set:HashMap<ID,T>)->Self{
|
|
||||||
Self{
|
|
||||||
extra:initial_set,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<ID:Eq+std::hash::Hash,T> SetDifferenceCheckContextAllowNone<ID,T>{
|
|
||||||
/// Compute the SetDifferenceCheck result for the specified reference set.
|
|
||||||
fn check<U>(mut self,reference_set:&HashMap<ID,U>)->SetDifferenceCheck<Self>{
|
|
||||||
// remove correct entries
|
|
||||||
for id in reference_set.keys(){
|
|
||||||
self.extra.remove(id);
|
|
||||||
}
|
|
||||||
// if any entries remain, they are incorrect
|
|
||||||
if self.extra.is_empty(){
|
|
||||||
SetDifferenceCheck(Ok(()))
|
|
||||||
}else{
|
|
||||||
SetDifferenceCheck(Err(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<ID,T> SetDifferenceCheckContextAtLeastOne<ID,T>{
|
|
||||||
fn new(initial_set:HashMap<ID,T>)->Self{
|
|
||||||
Self{
|
|
||||||
extra:initial_set,
|
|
||||||
missing:HashSet::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<ID:Copy+Eq+std::hash::Hash,T> SetDifferenceCheckContextAtLeastOne<ID,T>{
|
|
||||||
/// Compute the SetDifferenceCheck result for the specified reference set.
|
|
||||||
fn check<U>(mut self,reference_set:&HashMap<ID,U>)->SetDifferenceCheck<Self>{
|
|
||||||
// remove correct entries
|
|
||||||
for id in reference_set.keys(){
|
|
||||||
if self.extra.remove(id).is_none(){
|
|
||||||
// the set did not contain a required item. This is a fail
|
|
||||||
self.missing.insert(*id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if any entries remain, they are incorrect
|
|
||||||
if self.extra.is_empty()&&self.missing.is_empty(){
|
|
||||||
SetDifferenceCheck(Ok(()))
|
|
||||||
}else{
|
|
||||||
SetDifferenceCheck(Err(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Info lifted out of a fully compliant map
|
|
||||||
pub struct MapInfoOwned{
|
|
||||||
pub display_name:String,
|
|
||||||
pub creator:String,
|
|
||||||
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
|
|
||||||
struct Exists;
|
|
||||||
struct Absent;
|
|
||||||
|
|
||||||
/// The result of every map check.
|
|
||||||
struct MapCheck<'a>{
|
|
||||||
// === METADATA CHECKS ===
|
|
||||||
// The root must be of class Model
|
|
||||||
model_class:StringCheck<'a,(),&'static str>,
|
|
||||||
// Model's name must be in snake case
|
|
||||||
model_name:StringCheck<'a,(),String>,
|
|
||||||
// Map must have a StringValue named DisplayName.
|
|
||||||
// Value must not be empty, must be in title case.
|
|
||||||
display_name:Result<Result<StringCheck<'a,&'a str,String>,StringEmpty>,StringValueError>,
|
|
||||||
// Map must have a StringValue named Creator.
|
|
||||||
// Value must not be empty.
|
|
||||||
creator:Result<Result<&'a str,StringEmpty>,StringValueError>,
|
|
||||||
// The prefix of the model's name must match the game it was submitted for.
|
|
||||||
// bhop_ for bhop, and surf_ for surf
|
|
||||||
game_id:Result<GameID,ParseGameIDError>,
|
|
||||||
|
|
||||||
// === MODE CHECKS ===
|
|
||||||
// MapStart must exist
|
|
||||||
mapstart:Result<Exists,Absent>,
|
|
||||||
// No duplicate map starts (including bonuses)
|
|
||||||
mode_start_counts:DuplicateCheck<ModeID,Vec<&'a Instance>>,
|
|
||||||
// At least one finish zone for each start zone, and no finishes with no start
|
|
||||||
mode_finish_counts:SetDifferenceCheck<SetDifferenceCheckContextAtLeastOne<ModeID,Vec<&'a Instance>>>,
|
|
||||||
// Check for dangling MapAnticheat zones (no associated MapStart)
|
|
||||||
mode_anticheat_counts:SetDifferenceCheck<SetDifferenceCheckContextAllowNone<ModeID,Vec<&'a Instance>>>,
|
|
||||||
// Spawn1 must exist
|
|
||||||
spawn1:Result<Exists,Absent>,
|
|
||||||
// Check for dangling Teleport# (no associated Spawn#)
|
|
||||||
teleport_counts:SetDifferenceCheck<SetDifferenceCheckContextAllowNone<StageID,Vec<&'a Instance>>>,
|
|
||||||
// No duplicate Spawn#
|
|
||||||
spawn_counts:DuplicateCheck<StageID,u64>,
|
|
||||||
// Check for dangling WormholeIn# (no associated WormholeOut#)
|
|
||||||
wormhole_in_counts:SetDifferenceCheck<SetDifferenceCheckContextAtLeastOne<WormholeID,u64>>,
|
|
||||||
// No duplicate WormholeOut# (duplicate WormholeIn# ok)
|
|
||||||
// No dangling WormholeOut#
|
|
||||||
wormhole_out_counts:DuplicateCheck<WormholeID,u64>,
|
|
||||||
|
|
||||||
// === GENERAL CHECKS ===
|
|
||||||
unanchored_parts:Result<(),Vec<&'a Instance>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ModelInfo<'a>{
|
|
||||||
fn check(self)->MapCheck<'a>{
|
|
||||||
// Check class is exactly "Model"
|
|
||||||
let model_class=StringCheckContext{
|
|
||||||
observed:self.model_class,
|
|
||||||
expected:"Model",
|
|
||||||
}.check(());
|
|
||||||
|
|
||||||
// Check model name is snake case
|
|
||||||
let model_name=StringCheckContext{
|
|
||||||
observed:self.model_name,
|
|
||||||
expected:self.model_name.to_snake_case(),
|
|
||||||
}.check(());
|
|
||||||
|
|
||||||
// Check display name is not empty and has title case
|
|
||||||
let display_name=self.map_info.display_name.map(|display_name|{
|
|
||||||
check_empty(display_name).map(|display_name|StringCheckContext{
|
|
||||||
observed:display_name,
|
|
||||||
expected:display_name.to_title_case(),
|
|
||||||
}.check(display_name))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check Creator is not empty
|
|
||||||
let creator=self.map_info.creator.map(check_empty);
|
|
||||||
|
|
||||||
// Check GameID (model name was prefixed with bhop_ surf_ etc)
|
|
||||||
let game_id=self.map_info.game_id;
|
|
||||||
|
|
||||||
// MapStart must exist
|
|
||||||
let mapstart=if self.counts.mode_start_counts.contains_key(&ModeID::MAIN){
|
|
||||||
Ok(Exists)
|
|
||||||
}else{
|
|
||||||
Err(Absent)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Spawn1 must exist
|
|
||||||
let spawn1=if self.counts.spawn_counts.contains_key(&StageID::FIRST){
|
|
||||||
Ok(Exists)
|
|
||||||
}else{
|
|
||||||
Err(Absent)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check that at least one finish zone exists for each start zone.
|
|
||||||
// This also checks that there are no finish zones without a corresponding start zone.
|
|
||||||
let mode_finish_counts=SetDifferenceCheckContextAtLeastOne::new(self.counts.mode_finish_counts)
|
|
||||||
.check(&self.counts.mode_start_counts);
|
|
||||||
|
|
||||||
// Check that there are no anticheat zones without a corresponding start zone.
|
|
||||||
// Modes are allowed to have 0 anticheat zones.
|
|
||||||
let mode_anticheat_counts=SetDifferenceCheckContextAllowNone::new(self.counts.mode_anticheat_counts)
|
|
||||||
.check(&self.counts.mode_start_counts);
|
|
||||||
|
|
||||||
// There must be exactly one start zone for every mode in the map.
|
|
||||||
let mode_start_counts=DuplicateCheckContext(self.counts.mode_start_counts).check(|c|1<c.len());
|
|
||||||
|
|
||||||
// Check that there are no Teleports without a corresponding Spawn.
|
|
||||||
// Spawns are allowed to have 0 Teleports.
|
|
||||||
let teleport_counts=SetDifferenceCheckContextAllowNone::new(self.counts.teleport_counts)
|
|
||||||
.check(&self.counts.spawn_counts);
|
|
||||||
|
|
||||||
// There must be exactly one of any perticular spawn id in the map.
|
|
||||||
let spawn_counts=DuplicateCheckContext(self.counts.spawn_counts).check(|&c|1<c);
|
|
||||||
|
|
||||||
// Check that at least one WormholeIn exists for each WormholeOut.
|
|
||||||
// This also checks that there are no WormholeIn without a corresponding WormholeOut.
|
|
||||||
let wormhole_in_counts=SetDifferenceCheckContextAtLeastOne::new(self.counts.wormhole_in_counts)
|
|
||||||
.check(&self.counts.wormhole_out_counts);
|
|
||||||
|
|
||||||
// There must be exactly one of any perticular wormhole out id in the map.
|
|
||||||
let wormhole_out_counts=DuplicateCheckContext(self.counts.wormhole_out_counts).check(|&c|1<c);
|
|
||||||
|
|
||||||
// There must not be any unanchored parts
|
|
||||||
let unanchored_parts=if self.unanchored_parts.is_empty(){
|
|
||||||
Ok(())
|
|
||||||
}else{
|
|
||||||
Err(self.unanchored_parts)
|
|
||||||
};
|
|
||||||
|
|
||||||
MapCheck{
|
|
||||||
model_class,
|
|
||||||
model_name,
|
|
||||||
display_name,
|
|
||||||
creator,
|
|
||||||
game_id,
|
|
||||||
mapstart,
|
|
||||||
mode_start_counts,
|
|
||||||
mode_finish_counts,
|
|
||||||
mode_anticheat_counts,
|
|
||||||
spawn1,
|
|
||||||
teleport_counts,
|
|
||||||
spawn_counts,
|
|
||||||
wormhole_in_counts,
|
|
||||||
wormhole_out_counts,
|
|
||||||
unanchored_parts,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MapCheck<'_>{
|
|
||||||
fn result(self)->Result<MapInfoOwned,Result<MapCheckList,serde_json::Error>>{
|
|
||||||
match self{
|
|
||||||
MapCheck{
|
|
||||||
model_class:StringCheck(Ok(())),
|
|
||||||
model_name:StringCheck(Ok(())),
|
|
||||||
display_name:Ok(Ok(StringCheck(Ok(display_name)))),
|
|
||||||
creator:Ok(Ok(creator)),
|
|
||||||
game_id:Ok(game_id),
|
|
||||||
mapstart:Ok(Exists),
|
|
||||||
mode_start_counts:DuplicateCheck(Ok(())),
|
|
||||||
mode_finish_counts:SetDifferenceCheck(Ok(())),
|
|
||||||
mode_anticheat_counts:SetDifferenceCheck(Ok(())),
|
|
||||||
spawn1:Ok(Exists),
|
|
||||||
teleport_counts:SetDifferenceCheck(Ok(())),
|
|
||||||
spawn_counts:DuplicateCheck(Ok(())),
|
|
||||||
wormhole_in_counts:SetDifferenceCheck(Ok(())),
|
|
||||||
wormhole_out_counts:DuplicateCheck(Ok(())),
|
|
||||||
unanchored_parts:Ok(()),
|
|
||||||
}=>{
|
|
||||||
Ok(MapInfoOwned{
|
|
||||||
display_name:display_name.to_owned(),
|
|
||||||
creator:creator.to_owned(),
|
|
||||||
game_id,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
other=>Err(other.itemize()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Separated<F>{
|
|
||||||
f:F,
|
|
||||||
separator:&'static str,
|
|
||||||
}
|
|
||||||
impl<F> Separated<F>{
|
|
||||||
fn new(separator:&'static str,f:F)->Self{
|
|
||||||
Self{separator,f}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<F,I,D> std::fmt::Display for Separated<F>
|
|
||||||
where
|
|
||||||
D:std::fmt::Display,
|
|
||||||
I:IntoIterator<Item=D>,
|
|
||||||
F:Fn()->I,
|
|
||||||
{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
let mut it=(self.f)().into_iter();
|
|
||||||
if let Some(first)=it.next(){
|
|
||||||
write!(f,"{first}")?;
|
|
||||||
for item in it{
|
|
||||||
write!(f,"{}{item}",self.separator)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Duplicates<D>{
|
|
||||||
display:D,
|
|
||||||
duplicates:usize,
|
|
||||||
}
|
|
||||||
impl<D> Duplicates<D>{
|
|
||||||
fn new(display:D,duplicates:usize)->Self{
|
|
||||||
Self{
|
|
||||||
display,
|
|
||||||
duplicates,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<D:std::fmt::Display> std::fmt::Display for Duplicates<D>{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"{} ({} duplicates)",self.display,self.duplicates)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! passed{
|
|
||||||
($name:literal)=>{
|
|
||||||
Check{
|
|
||||||
name:$name.to_owned(),
|
|
||||||
summary:String::new(),
|
|
||||||
passed:true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
macro_rules! summary{
|
|
||||||
($name:literal,$summary:expr)=>{
|
|
||||||
Check{
|
|
||||||
name:$name.to_owned(),
|
|
||||||
summary:$summary,
|
|
||||||
passed:false,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
macro_rules! summary_format{
|
|
||||||
($name:literal,$fmt:literal)=>{
|
|
||||||
Check{
|
|
||||||
name:$name.to_owned(),
|
|
||||||
summary:format!($fmt),
|
|
||||||
passed:false,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate an error message for each observed issue separated by newlines.
|
|
||||||
// This defines MapCheck.to_string() which is used in MapCheck.result()
|
|
||||||
impl MapCheck<'_>{
|
|
||||||
fn itemize(&self)->Result<MapCheckList,serde_json::Error>{
|
|
||||||
let model_class=match &self.model_class{
|
|
||||||
StringCheck(Ok(()))=>passed!("ModelClass"),
|
|
||||||
StringCheck(Err(context))=>summary_format!("ModelClass","Invalid model class: {context}"),
|
|
||||||
};
|
|
||||||
let model_name=match &self.model_name{
|
|
||||||
StringCheck(Ok(()))=>passed!("ModelName"),
|
|
||||||
StringCheck(Err(context))=>summary_format!("ModelName","Model name must have snake_case: {context}"),
|
|
||||||
};
|
|
||||||
let display_name=match &self.display_name{
|
|
||||||
Ok(Ok(StringCheck(Ok(_))))=>passed!("DisplayName"),
|
|
||||||
Ok(Ok(StringCheck(Err(context))))=>summary_format!("DisplayName","DisplayName must have Title Case: {context}"),
|
|
||||||
Ok(Err(context))=>summary_format!("DisplayName","Invalid DisplayName: {context}"),
|
|
||||||
Err(StringValueError::ObjectNotFound)=>summary!("DisplayName","Missing DisplayName StringValue".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()),
|
|
||||||
};
|
|
||||||
let creator=match &self.creator{
|
|
||||||
Ok(Ok(_))=>passed!("Creator"),
|
|
||||||
Ok(Err(context))=>summary_format!("Creator","Invalid Creator: {context}"),
|
|
||||||
Err(StringValueError::ObjectNotFound)=>summary!("Creator","Missing Creator StringValue".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()),
|
|
||||||
};
|
|
||||||
let game_id=match &self.game_id{
|
|
||||||
Ok(_)=>passed!("GameID"),
|
|
||||||
Err(ParseGameIDError)=>summary!("GameID","Model name must be prefixed with bhop_ surf_ or flytrials_".to_owned()),
|
|
||||||
};
|
|
||||||
let mapstart=match &self.mapstart{
|
|
||||||
Ok(Exists)=>passed!("MapStart"),
|
|
||||||
Err(Absent)=>summary_format!("MapStart","Model has no MapStart"),
|
|
||||||
};
|
|
||||||
let duplicate_start=match &self.mode_start_counts{
|
|
||||||
DuplicateCheck(Ok(()))=>passed!("DuplicateStart"),
|
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&mode_id,instances)|
|
|
||||||
Duplicates::new(ModeElement{zone:Zone::Start,mode_id},instances.len())
|
|
||||||
));
|
|
||||||
summary_format!("DuplicateStart","Duplicate start zones: {context}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let (extra_finish,missing_finish)=match &self.mode_finish_counts{
|
|
||||||
SetDifferenceCheck(Ok(()))=>(passed!("DanglingFinish"),passed!("MissingFinish")),
|
|
||||||
SetDifferenceCheck(Err(context))=>(
|
|
||||||
if context.extra.is_empty(){
|
|
||||||
passed!("DanglingFinish")
|
|
||||||
}else{
|
|
||||||
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_instances)|
|
|
||||||
ModeElement{zone:Zone::Finish,mode_id}
|
|
||||||
));
|
|
||||||
summary_format!("DanglingFinish","No matching start zone for finish {plural}: {context}")
|
|
||||||
},
|
|
||||||
if context.missing.is_empty(){
|
|
||||||
passed!("MissingFinish")
|
|
||||||
}else{
|
|
||||||
let plural=if context.missing.len()==1{"zone"}else{"zones"};
|
|
||||||
let context=Separated::new(", ",||context.missing.iter().map(|&mode_id|
|
|
||||||
ModeElement{zone:Zone::Finish,mode_id}
|
|
||||||
));
|
|
||||||
summary_format!("MissingFinish","Missing finish {plural}: {context}")
|
|
||||||
}
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let dangling_anticheat=match &self.mode_anticheat_counts{
|
|
||||||
SetDifferenceCheck(Ok(()))=>passed!("DanglingAnticheat"),
|
|
||||||
SetDifferenceCheck(Err(context))=>{
|
|
||||||
if context.extra.is_empty(){
|
|
||||||
passed!("DanglingAnticheat")
|
|
||||||
}else{
|
|
||||||
let plural=if context.extra.len()==1{"zone"}else{"zones"};
|
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&mode_id,_instances)|
|
|
||||||
ModeElement{zone:Zone::Anticheat,mode_id}
|
|
||||||
));
|
|
||||||
summary_format!("DanglingAnticheat","No matching start zone for anticheat {plural}: {context}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let spawn1=match &self.spawn1{
|
|
||||||
Ok(Exists)=>passed!("Spawn1"),
|
|
||||||
Err(Absent)=>summary_format!("Spawn1","Model has no Spawn1"),
|
|
||||||
};
|
|
||||||
let dangling_teleport=match &self.teleport_counts{
|
|
||||||
SetDifferenceCheck(Ok(()))=>passed!("DanglingTeleport"),
|
|
||||||
SetDifferenceCheck(Err(context))=>{
|
|
||||||
let unique_names:HashSet<_>=context.extra.values().flat_map(|instances|
|
|
||||||
instances.iter().map(|instance|instance.name.as_str())
|
|
||||||
).collect();
|
|
||||||
let plural=if unique_names.len()==1{"object"}else{"objects"};
|
|
||||||
let context=Separated::new(", ",||&unique_names);
|
|
||||||
summary_format!("DanglingTeleport","No matching Spawn for {plural}: {context}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let duplicate_spawns=match &self.spawn_counts{
|
|
||||||
DuplicateCheck(Ok(()))=>passed!("DuplicateSpawn"),
|
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&stage_id,&instances)|
|
|
||||||
Duplicates::new(StageElement{behaviour:StageElementBehaviour::Spawn,stage_id},instances as usize)
|
|
||||||
));
|
|
||||||
summary_format!("DuplicateSpawn","Duplicate Spawn: {context}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let (extra_wormhole_in,missing_wormhole_in)=match &self.wormhole_in_counts{
|
|
||||||
SetDifferenceCheck(Ok(()))=>(passed!("ExtraWormholeIn"),passed!("MissingWormholeIn")),
|
|
||||||
SetDifferenceCheck(Err(context))=>(
|
|
||||||
if context.extra.is_empty(){
|
|
||||||
passed!("ExtraWormholeIn")
|
|
||||||
}else{
|
|
||||||
let context=Separated::new(", ",||context.extra.iter().map(|(&wormhole_id,_instances)|
|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::In,wormhole_id}
|
|
||||||
));
|
|
||||||
summary_format!("ExtraWormholeIn","WormholeIn with no matching WormholeOut: {context}")
|
|
||||||
},
|
|
||||||
if context.missing.is_empty(){
|
|
||||||
passed!("MissingWormholeIn")
|
|
||||||
}else{
|
|
||||||
// This counts WormholeIn objects, but
|
|
||||||
// flipped logic is easier to understand
|
|
||||||
let context=Separated::new(", ",||context.missing.iter().map(|&wormhole_id|
|
|
||||||
WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id}
|
|
||||||
));
|
|
||||||
summary_format!("MissingWormholeIn","WormholeOut with no matching WormholeIn: {context}")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let duplicate_wormhole_out=match &self.wormhole_out_counts{
|
|
||||||
DuplicateCheck(Ok(()))=>passed!("DuplicateWormholeOut"),
|
|
||||||
DuplicateCheck(Err(DuplicateCheckContext(context)))=>{
|
|
||||||
let context=Separated::new(", ",||context.iter().map(|(&wormhole_id,&instances)|
|
|
||||||
Duplicates::new(WormholeElement{behaviour:WormholeBehaviour::Out,wormhole_id},instances as usize)
|
|
||||||
));
|
|
||||||
summary_format!("DuplicateWormholeOut","Duplicate WormholeOut: {context}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let unanchored_parts=match &self.unanchored_parts{
|
|
||||||
Ok(())=>passed!("UnanchoredParts"),
|
|
||||||
Err(unanchored_parts)=>{
|
|
||||||
let count=unanchored_parts.len();
|
|
||||||
let plural=if count==1{"part"}else{"parts"};
|
|
||||||
let context=Separated::new(", ",||unanchored_parts.iter().map(|&instance|
|
|
||||||
instance.name.as_str()
|
|
||||||
).take(20));
|
|
||||||
summary_format!("UnanchoredParts","{count} unanchored {plural}: {context}")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(MapCheckList{checks:vec![
|
|
||||||
model_class,
|
|
||||||
model_name,
|
|
||||||
display_name,
|
|
||||||
creator,
|
|
||||||
game_id,
|
|
||||||
mapstart,
|
|
||||||
duplicate_start,
|
|
||||||
extra_finish,
|
|
||||||
missing_finish,
|
|
||||||
dangling_anticheat,
|
|
||||||
spawn1,
|
|
||||||
dangling_teleport,
|
|
||||||
duplicate_spawns,
|
|
||||||
extra_wormhole_in,
|
|
||||||
missing_wormhole_in,
|
|
||||||
duplicate_wormhole_out,
|
|
||||||
unanchored_parts,
|
|
||||||
]})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
|
||||||
pub struct MapCheckList{
|
|
||||||
pub checks:Vec<Check>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CheckListAndVersion{
|
|
||||||
pub status:Result<MapInfoOwned,MapCheckList>,
|
|
||||||
pub version:u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl crate::message_handler::MessageHandler{
|
|
||||||
pub async fn check_inner(&self,check_info:CheckRequest)->Result<CheckListAndVersion,Error>{
|
|
||||||
// discover asset creator and latest version
|
|
||||||
let info=self.cloud_context.get_asset_info(
|
|
||||||
rbx_asset::cloud::GetAssetLatestRequest{asset_id:check_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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// parse model version string
|
|
||||||
let version=info.revisionId;
|
|
||||||
|
|
||||||
let maybe_gzip=download_asset_version(&self.cloud_context,rbx_asset::cloud::GetAssetVersionRequest{
|
|
||||||
asset_id:check_info.ModelID,
|
|
||||||
version,
|
|
||||||
}).await.map_err(Error::Download)?;
|
|
||||||
|
|
||||||
// decode dom (slow!)
|
|
||||||
let dom=maybe_gzip.read_with(read_dom,read_dom).map_err(Error::ModelFileDecode)?;
|
|
||||||
|
|
||||||
// extract the root instance
|
|
||||||
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
|
|
||||||
let model_info=get_model_info(&dom,model_instance);
|
|
||||||
|
|
||||||
// convert the model information into a structured report
|
|
||||||
let map_check=model_info.check();
|
|
||||||
|
|
||||||
// check the report, generate an error message if it fails the check
|
|
||||||
let status=match map_check.result(){
|
|
||||||
Ok(map_info)=>Ok(map_info),
|
|
||||||
Err(Ok(check_list))=>Err(check_list),
|
|
||||||
Err(Err(e))=>return Err(Error::ToJsonValue(e)),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(CheckListAndVersion{status,version})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user