3 Commits

Author SHA1 Message Date
bf0a6c63cd form values encode to json
All checks were successful
continuous-integration/drone/push Build is passing
explicit errors for each value is implemented -
TODO: show the error to the user with html text instead of printing it
2024-12-15 14:26:00 -05:00
51d812b3ad web: change buttons
All checks were successful
continuous-integration/drone/push Build is passing
2024-12-14 11:35:11 -08:00
a83ab272bb releaser: run me to batch release maps 2024-12-14 11:18:32 -08:00
99 changed files with 5782 additions and 12273 deletions

View File

@@ -1,5 +1,5 @@
submissions:
DOCKER_BUILDKIT=1 docker build . -f Containerfile -t maps-service-submissions
maps-service:
DOCKER_BUILDKIT=1 docker build . -f Containerfile -t maps-service
web:
docker build web -f web/Containerfile -t maps-service-web
@@ -7,6 +7,6 @@ web:
validation:
docker build validation -f validation/Containerfile -t maps-service-validation
all: submissions web validation
all: maps-service web validation
.PHONY: submissions web validation
.PHONY: maps-service web validation

View File

@@ -11,17 +11,15 @@ services:
networks:
- maps-service-network
submissions:
mapsservice:
image:
maps-service-submissions
container_name: submissions
maps-service
container_name: mapsservice
command: [
# debug
"--debug","serve",
# http service port
"--port","8082",
# internal http endpoints
"--port-internal","8083",
# postgres
"--pg-host","10.0.0.29",
"--pg-port","5432",
@@ -52,18 +50,16 @@ services:
image:
maps-service-validation
container_name: validation
env_file:
- ../auth-compose/strafesnet_staging.env
environment:
- ROBLOX_GROUP_ID=17032139 # "None" is special case string value
- API_HOST_INTERNAL=http://submissions:8083
- RBXCOOKIE
- API_HOST=http://mapsservice:8082
- NATS_HOST=nats:4222
- DATA_HOST=http://dataservice:9000
depends_on:
- nats
# note: this races the submissions which creates a nats stream
# note: this races the mapsservice which creates a nats stream
# the validation will panic if the nats stream is not created
- submissions
- mapsservice
- dataservice
networks:
- maps-service-network
@@ -91,9 +87,9 @@ services:
- maps-service-network
authrpc:
image: registry.itzana.me/strafesnet/auth-service:staging
image: registry.itzana.me/strafesnet/auth-service:master
container_name: authrpc
command: ["--debug", "serve", "rpc"]
command: ["serve", "rpc"]
environment:
- REDIS_ADDR=authredis:6379
env_file:
@@ -106,7 +102,7 @@ services:
driver: "none"
auth-web:
image: registry.itzana.me/strafesnet/auth-service:staging
image: registry.itzana.me/strafesnet/auth-service:master
command: ["serve", "web"]
environment:
- REDIS_ADDR=authredis:6379

View File

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

View File

@@ -1,399 +0,0 @@
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: Submissions
description: Submission operations
paths:
/submissions/{SubmissionID}/model:
post:
summary: Update model following role restrictions
operationId: updateSubmissionModel
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ModelID
in: query
required: true
schema:
type: integer
format: int64
- name: VersionID
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'
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: TargetAssetID
in: query
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/releaser-released:
post:
summary: (Internal endpoint) Role Releaser changes status from releasing -> released
operationId: actionSubmissionReleased
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/script-policy:
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/Id"
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: SubmissionID
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/Id"
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:
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:
Id:
required:
- ID
type: object
properties:
ID:
type: integer
format: int64
Script:
required:
- ID
- Name
- Hash
- Source
- SubmissionID
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
SubmissionID:
type: integer
format: int64
ScriptCreate:
required:
- Name
- Source
# - SubmissionID
type: object
properties:
Name:
type: string
maxLength: 128
Source:
type: string
maxLength: 1048576
SubmissionID:
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

View File

@@ -12,8 +12,6 @@ tags:
description: Script operations
- name: ScriptPolicy
description: Script policy operations
security:
- cookieAuth: []
paths:
/submissions:
get:
@@ -21,24 +19,21 @@ paths:
operationId: listSubmissions
tags:
- Submissions
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/Limit"
- name: DisplayName
in: query
schema:
type: string
maxLength: 128
- name: Creator
in: query
schema:
type: string
maxLength: 128
- name: GameID
in: query
schema:
type: integer
format: int32
requestBody:
required: true
content:
application/json:
schema:
required:
- Page
type: object
properties:
Page:
$ref: "#/components/schemas/Pagination"
Filter:
$ref: "#/components/schemas/SubmissionFilter"
security:
- cookieAuth: []
responses:
"200":
description: Successful response
@@ -65,6 +60,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/SubmissionCreate'
security:
- cookieAuth: []
responses:
"201":
description: Successful response
@@ -86,6 +83,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"200":
description: Successful response
@@ -119,6 +118,8 @@ paths:
schema:
type: integer
format: int64
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -136,6 +137,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -153,6 +156,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -170,6 +175,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -187,6 +194,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -204,6 +213,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -221,6 +232,8 @@ paths:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -230,10 +243,10 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/trigger-upload:
/submissions/{SubmissionID}/status/validator-validated:
post:
summary: Role Admin changes status from Validated -> Uploading
operationId: actionSubmissionTriggerUpload
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
operationId: actionSubmissionValidate
tags:
- Submissions
parameters:
@@ -247,31 +260,63 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-published:
post:
summary: (Internal endpoint) Role Validator changes status from Publishing -> Published
operationId: actionSubmissionPublish
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/trigger-publish:
post:
summary: Role Admin changes status from Validated -> Publishing
operationId: actionSubmissionTriggerPublish
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
security:
- cookieAuth: []
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
requestBody:
required: true
content:
application/json:
schema:
required:
- Page
type: object
properties:
Page:
$ref: "#/components/schemas/Pagination"
Filter:
$ref: "#/components/schemas/ScriptPolicyFilter"
security:
- cookieAuth: []
responses:
"200":
description: Successful response
@@ -298,6 +343,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ScriptPolicyCreate'
security:
- cookieAuth: []
responses:
"201":
description: Successful response
@@ -311,7 +358,36 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/script-policy/{ScriptPolicyID}:
/script-policy/hash/{FromScriptHash}:
get:
summary: Get the policy for the given hash of script source code
operationId: getScriptPolicyFromHash
tags:
- ScriptPolicy
parameters:
- name: FromScriptHash
in: path
required: true
schema:
type: string
minLength: 16
maxLength: 16
security:
- cookieAuth: []
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/ScriptPolicy"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/script-policy/id/{ScriptPolicyID}:
get:
summary: Get the specified script policy by ID
operationId: getScriptPolicy
@@ -319,6 +395,8 @@ paths:
- ScriptPolicy
parameters:
- $ref: '#/components/parameters/ScriptPolicyID'
security:
- cookieAuth: []
responses:
"200":
description: Successful response
@@ -345,6 +423,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ScriptPolicyUpdate'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -361,6 +441,8 @@ paths:
- ScriptPolicy
parameters:
- $ref: '#/components/parameters/ScriptPolicyID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -371,50 +453,6 @@ paths:
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: SubmissionID
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
@@ -426,6 +464,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ScriptCreate'
security:
- cookieAuth: []
responses:
"201":
description: Successful response
@@ -447,6 +487,8 @@ paths:
- Scripts
parameters:
- $ref: '#/components/parameters/ScriptID'
security:
- cookieAuth: []
responses:
"200":
description: Successful response
@@ -473,6 +515,8 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ScriptUpdate'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -489,6 +533,8 @@ paths:
- Scripts
parameters:
- $ref: '#/components/parameters/ScriptID'
security:
- cookieAuth: []
responses:
"204":
description: Successful response
@@ -529,23 +575,6 @@ components:
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:
Id:
required:
@@ -610,6 +639,23 @@ components:
StatusID:
type: integer
format: int32
SubmissionFilter:
required:
- ID
type: object
properties:
ID:
type: integer
format: int64
DisplayName:
type: string
maxLength: 128
Creator:
type: string
maxLength: 128
GameID:
type: integer
format: int32
SubmissionCreate:
required:
- DisplayName
@@ -641,7 +687,6 @@ components:
Script:
required:
- ID
- Name
- Hash
- Source
- SubmissionID
@@ -650,9 +695,6 @@ components:
ID:
type: integer
format: int64
Name:
type: string
maxLength: 128
Hash:
type: string
minLength: 16
@@ -665,14 +707,10 @@ components:
format: int64
ScriptCreate:
required:
- Name
- Source
# - SubmissionID
type: object
properties:
Name:
type: string
maxLength: 128
Source:
type: string
maxLength: 1048576
@@ -687,9 +725,6 @@ components:
ID:
type: integer
format: int64
Name:
type: string
maxLength: 128
Source:
type: string
maxLength: 1048576
@@ -717,6 +752,22 @@ components:
Policy:
type: integer
format: int32
ScriptPolicyFilter:
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
@@ -750,6 +801,21 @@ components:
Policy:
type: integer
format: int32
Pagination:
type: object
required:
- Page
- Limit
properties:
Page:
type: integer
format: int32
minimum: 1
Limit:
type: integer
format: int32
minimum: 1
maximum: 100
Error:
description: Represents error object
type: object

View File

@@ -24,6 +24,12 @@ import (
// Invoker invokes operations described by OpenAPI v3 specification.
type Invoker interface {
// ActionSubmissionPublish invokes actionSubmissionPublish operation.
//
// (Internal endpoint) Role Validator changes status from Publishing -> Published.
//
// POST /submissions/{SubmissionID}/status/validator-published
ActionSubmissionPublish(ctx context.Context, params ActionSubmissionPublishParams) error
// ActionSubmissionReject invokes actionSubmissionReject operation.
//
// Role Reviewer changes status from Submitted -> Rejected.
@@ -48,18 +54,24 @@ type Invoker interface {
//
// POST /submissions/{SubmissionID}/status/submit
ActionSubmissionSubmit(ctx context.Context, params ActionSubmissionSubmitParams) error
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
//
// Role Admin changes status from Validated -> Uploading.
// Role Admin changes status from Validated -> Publishing.
//
// POST /submissions/{SubmissionID}/status/trigger-upload
ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error
// POST /submissions/{SubmissionID}/status/trigger-publish
ActionSubmissionTriggerPublish(ctx context.Context, params ActionSubmissionTriggerPublishParams) error
// ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation.
//
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
//
// POST /submissions/{SubmissionID}/status/trigger-validate
ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error
// CreateScript invokes createScript operation.
//
// Create a new script.
@@ -88,7 +100,7 @@ type Invoker interface {
//
// Delete the specified script policy by ID.
//
// DELETE /script-policy/{ScriptPolicyID}
// DELETE /script-policy/id/{ScriptPolicyID}
DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error
// GetScript invokes getScript operation.
//
@@ -100,8 +112,14 @@ type Invoker interface {
//
// Get the specified script policy by ID.
//
// GET /script-policy/{ScriptPolicyID}
// GET /script-policy/id/{ScriptPolicyID}
GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error)
// GetScriptPolicyFromHash invokes getScriptPolicyFromHash operation.
//
// Get the policy for the given hash of script source code.
//
// GET /script-policy/hash/{FromScriptHash}
GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error)
// GetSubmission invokes getSubmission operation.
//
// Retrieve map with ID.
@@ -113,19 +131,13 @@ type Invoker interface {
// Get list of script policies.
//
// GET /script-policy
ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) ([]ScriptPolicy, error)
// ListScripts invokes listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error)
ListScriptPolicy(ctx context.Context, request *ListScriptPolicyReq) ([]ScriptPolicy, error)
// ListSubmissions invokes listSubmissions operation.
//
// Get list of submissions.
//
// GET /submissions
ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error)
ListSubmissions(ctx context.Context, request *ListSubmissionsReq) ([]Submission, error)
// SetSubmissionCompleted invokes setSubmissionCompleted operation.
//
// Retrieve map with ID.
@@ -142,7 +154,7 @@ type Invoker interface {
//
// Update the specified script policy by ID.
//
// POST /script-policy/{ScriptPolicyID}
// POST /script-policy/id/{ScriptPolicyID}
UpdateScriptPolicy(ctx context.Context, request *ScriptPolicyUpdate, params UpdateScriptPolicyParams) error
// UpdateSubmissionModel invokes updateSubmissionModel operation.
//
@@ -206,6 +218,97 @@ func (c *Client) requestURL(ctx context.Context) *url.URL {
return u
}
// ActionSubmissionPublish invokes actionSubmissionPublish operation.
//
// (Internal endpoint) Role Validator changes status from Publishing -> Published.
//
// POST /submissions/{SubmissionID}/status/validator-published
func (c *Client) ActionSubmissionPublish(ctx context.Context, params ActionSubmissionPublishParams) error {
_, err := c.sendActionSubmissionPublish(ctx, params)
return err
}
func (c *Client) sendActionSubmissionPublish(ctx context.Context, params ActionSubmissionPublishParams) (res *ActionSubmissionPublishNoContent, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("actionSubmissionPublish"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/validator-published"),
}
// Run stopwatch.
startTime := time.Now()
defer func() {
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedDuration := time.Since(startTime)
c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...))
}()
// Increment request counter.
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
// Start a span for this request.
ctx, span := c.cfg.Tracer.Start(ctx, ActionSubmissionPublishOperation,
trace.WithAttributes(otelAttrs...),
clientSpanKind,
)
// Track stage for error reporting.
var stage string
defer func() {
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, stage)
c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
}
span.End()
}()
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [3]string
pathParts[0] = "/submissions/"
{
// Encode "SubmissionID" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{
Param: "SubmissionID",
Style: uri.PathStyleSimple,
Explode: false,
})
if err := func() error {
return e.EncodeValue(conv.Int64ToString(params.SubmissionID))
}(); err != nil {
return res, errors.Wrap(err, "encode path")
}
encoded, err := e.Result()
if err != nil {
return res, errors.Wrap(err, "encode path")
}
pathParts[1] = encoded
}
pathParts[2] = "/status/validator-published"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "POST", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
stage = "SendRequest"
resp, err := c.cfg.Client.Do(r)
if err != nil {
return res, errors.Wrap(err, "do request")
}
defer resp.Body.Close()
stage = "DecodeResponse"
result, err := decodeActionSubmissionPublishResponse(resp)
if err != nil {
return res, errors.Wrap(err, "decode response")
}
return result, nil
}
// ActionSubmissionReject invokes actionSubmissionReject operation.
//
// Role Reviewer changes status from Submitted -> Rejected.
@@ -702,21 +805,21 @@ func (c *Client) sendActionSubmissionSubmit(ctx context.Context, params ActionSu
return result, nil
}
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
//
// Role Admin changes status from Validated -> Uploading.
// Role Admin changes status from Validated -> Publishing.
//
// POST /submissions/{SubmissionID}/status/trigger-upload
func (c *Client) ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error {
_, err := c.sendActionSubmissionTriggerUpload(ctx, params)
// POST /submissions/{SubmissionID}/status/trigger-publish
func (c *Client) ActionSubmissionTriggerPublish(ctx context.Context, params ActionSubmissionTriggerPublishParams) error {
_, err := c.sendActionSubmissionTriggerPublish(ctx, params)
return err
}
func (c *Client) sendActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) (res *ActionSubmissionTriggerUploadNoContent, err error) {
func (c *Client) sendActionSubmissionTriggerPublish(ctx context.Context, params ActionSubmissionTriggerPublishParams) (res *ActionSubmissionTriggerPublishNoContent, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("actionSubmissionTriggerUpload"),
otelogen.OperationID("actionSubmissionTriggerPublish"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/trigger-upload"),
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/trigger-publish"),
}
// Run stopwatch.
@@ -731,7 +834,7 @@ func (c *Client) sendActionSubmissionTriggerUpload(ctx context.Context, params A
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
// Start a span for this request.
ctx, span := c.cfg.Tracer.Start(ctx, ActionSubmissionTriggerUploadOperation,
ctx, span := c.cfg.Tracer.Start(ctx, ActionSubmissionTriggerPublishOperation,
trace.WithAttributes(otelAttrs...),
clientSpanKind,
)
@@ -768,7 +871,7 @@ func (c *Client) sendActionSubmissionTriggerUpload(ctx context.Context, params A
}
pathParts[1] = encoded
}
pathParts[2] = "/status/trigger-upload"
pathParts[2] = "/status/trigger-publish"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeRequest"
@@ -782,7 +885,7 @@ func (c *Client) sendActionSubmissionTriggerUpload(ctx context.Context, params A
var satisfied bitset
{
stage = "Security:CookieAuth"
switch err := c.securityCookieAuth(ctx, ActionSubmissionTriggerUploadOperation, r); {
switch err := c.securityCookieAuth(ctx, ActionSubmissionTriggerPublishOperation, r); {
case err == nil: // if NO error
satisfied[0] |= 1 << 0
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
@@ -818,7 +921,7 @@ func (c *Client) sendActionSubmissionTriggerUpload(ctx context.Context, params A
defer resp.Body.Close()
stage = "DecodeResponse"
result, err := decodeActionSubmissionTriggerUploadResponse(resp)
result, err := decodeActionSubmissionTriggerPublishResponse(resp)
if err != nil {
return res, errors.Wrap(err, "decode response")
}
@@ -950,6 +1053,97 @@ func (c *Client) sendActionSubmissionTriggerValidate(ctx context.Context, params
return result, nil
}
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
func (c *Client) ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error {
_, err := c.sendActionSubmissionValidate(ctx, params)
return err
}
func (c *Client) sendActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) (res *ActionSubmissionValidateNoContent, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("actionSubmissionValidate"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/validator-validated"),
}
// Run stopwatch.
startTime := time.Now()
defer func() {
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedDuration := time.Since(startTime)
c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...))
}()
// Increment request counter.
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
// Start a span for this request.
ctx, span := c.cfg.Tracer.Start(ctx, ActionSubmissionValidateOperation,
trace.WithAttributes(otelAttrs...),
clientSpanKind,
)
// Track stage for error reporting.
var stage string
defer func() {
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, stage)
c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
}
span.End()
}()
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [3]string
pathParts[0] = "/submissions/"
{
// Encode "SubmissionID" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{
Param: "SubmissionID",
Style: uri.PathStyleSimple,
Explode: false,
})
if err := func() error {
return e.EncodeValue(conv.Int64ToString(params.SubmissionID))
}(); err != nil {
return res, errors.Wrap(err, "encode path")
}
encoded, err := e.Result()
if err != nil {
return res, errors.Wrap(err, "encode path")
}
pathParts[1] = encoded
}
pathParts[2] = "/status/validator-validated"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "POST", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
stage = "SendRequest"
resp, err := c.cfg.Client.Do(r)
if err != nil {
return res, errors.Wrap(err, "do request")
}
defer resp.Body.Close()
stage = "DecodeResponse"
result, err := decodeActionSubmissionValidateResponse(resp)
if err != nil {
return res, errors.Wrap(err, "decode response")
}
return result, nil
}
// CreateScript invokes createScript operation.
//
// Create a new script.
@@ -1401,7 +1595,7 @@ func (c *Client) sendDeleteScript(ctx context.Context, params DeleteScriptParams
//
// Delete the specified script policy by ID.
//
// DELETE /script-policy/{ScriptPolicyID}
// DELETE /script-policy/id/{ScriptPolicyID}
func (c *Client) DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error {
_, err := c.sendDeleteScriptPolicy(ctx, params)
return err
@@ -1411,7 +1605,7 @@ func (c *Client) sendDeleteScriptPolicy(ctx context.Context, params DeleteScript
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("deleteScriptPolicy"),
semconv.HTTPRequestMethodKey.String("DELETE"),
semconv.HTTPRouteKey.String("/script-policy/{ScriptPolicyID}"),
semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"),
}
// Run stopwatch.
@@ -1444,7 +1638,7 @@ func (c *Client) sendDeleteScriptPolicy(ctx context.Context, params DeleteScript
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [2]string
pathParts[0] = "/script-policy/"
pathParts[0] = "/script-policy/id/"
{
// Encode "ScriptPolicyID" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{
@@ -1647,7 +1841,7 @@ func (c *Client) sendGetScript(ctx context.Context, params GetScriptParams) (res
//
// Get the specified script policy by ID.
//
// GET /script-policy/{ScriptPolicyID}
// GET /script-policy/id/{ScriptPolicyID}
func (c *Client) GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error) {
res, err := c.sendGetScriptPolicy(ctx, params)
return res, err
@@ -1657,7 +1851,7 @@ func (c *Client) sendGetScriptPolicy(ctx context.Context, params GetScriptPolicy
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("getScriptPolicy"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/script-policy/{ScriptPolicyID}"),
semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"),
}
// Run stopwatch.
@@ -1690,7 +1884,7 @@ func (c *Client) sendGetScriptPolicy(ctx context.Context, params GetScriptPolicy
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [2]string
pathParts[0] = "/script-policy/"
pathParts[0] = "/script-policy/id/"
{
// Encode "ScriptPolicyID" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{
@@ -1766,6 +1960,129 @@ func (c *Client) sendGetScriptPolicy(ctx context.Context, params GetScriptPolicy
return result, nil
}
// GetScriptPolicyFromHash invokes getScriptPolicyFromHash operation.
//
// Get the policy for the given hash of script source code.
//
// GET /script-policy/hash/{FromScriptHash}
func (c *Client) GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error) {
res, err := c.sendGetScriptPolicyFromHash(ctx, params)
return res, err
}
func (c *Client) sendGetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (res *ScriptPolicy, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("getScriptPolicyFromHash"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/script-policy/hash/{FromScriptHash}"),
}
// Run stopwatch.
startTime := time.Now()
defer func() {
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedDuration := time.Since(startTime)
c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...))
}()
// Increment request counter.
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
// Start a span for this request.
ctx, span := c.cfg.Tracer.Start(ctx, GetScriptPolicyFromHashOperation,
trace.WithAttributes(otelAttrs...),
clientSpanKind,
)
// Track stage for error reporting.
var stage string
defer func() {
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, stage)
c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
}
span.End()
}()
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [2]string
pathParts[0] = "/script-policy/hash/"
{
// Encode "FromScriptHash" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{
Param: "FromScriptHash",
Style: uri.PathStyleSimple,
Explode: false,
})
if err := func() error {
return e.EncodeValue(conv.StringToString(params.FromScriptHash))
}(); err != nil {
return res, errors.Wrap(err, "encode path")
}
encoded, err := e.Result()
if err != nil {
return res, errors.Wrap(err, "encode path")
}
pathParts[1] = encoded
}
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "GET", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
{
type bitset = [1]uint8
var satisfied bitset
{
stage = "Security:CookieAuth"
switch err := c.securityCookieAuth(ctx, GetScriptPolicyFromHashOperation, r); {
case err == nil: // if NO error
satisfied[0] |= 1 << 0
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
// Skip this security.
default:
return res, errors.Wrap(err, "security \"CookieAuth\"")
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
}
}
stage = "SendRequest"
resp, err := c.cfg.Client.Do(r)
if err != nil {
return res, errors.Wrap(err, "do request")
}
defer resp.Body.Close()
stage = "DecodeResponse"
result, err := decodeGetScriptPolicyFromHashResponse(resp)
if err != nil {
return res, errors.Wrap(err, "decode response")
}
return result, nil
}
// GetSubmission invokes getSubmission operation.
//
// Retrieve map with ID.
@@ -1894,12 +2211,12 @@ func (c *Client) sendGetSubmission(ctx context.Context, params GetSubmissionPara
// Get list of script policies.
//
// GET /script-policy
func (c *Client) ListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) ([]ScriptPolicy, error) {
res, err := c.sendListScriptPolicy(ctx, params)
func (c *Client) ListScriptPolicy(ctx context.Context, request *ListScriptPolicyReq) ([]ScriptPolicy, error) {
res, err := c.sendListScriptPolicy(ctx, request)
return res, err
}
func (c *Client) sendListScriptPolicy(ctx context.Context, params ListScriptPolicyParams) (res []ScriptPolicy, err error) {
func (c *Client) sendListScriptPolicy(ctx context.Context, request *ListScriptPolicyReq) (res []ScriptPolicy, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listScriptPolicy"),
semconv.HTTPRequestMethodKey.String("GET"),
@@ -1939,94 +2256,14 @@ func (c *Client) sendListScriptPolicy(ctx context.Context, params ListScriptPoli
pathParts[0] = "/script-policy"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeQueryParams"
q := uri.NewQueryEncoder()
{
// Encode "Page" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Page",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Page))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Limit" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Limit",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Limit))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "FromScriptHash" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "FromScriptHash",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.FromScriptHash.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "ToScriptID" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "ToScriptID",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.ToScriptID.Get(); ok {
return e.EncodeValue(conv.Int64ToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Policy" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Policy",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.Policy.Get(); ok {
return e.EncodeValue(conv.Int32ToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
u.RawQuery = q.Values().Encode()
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "GET", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
if err := encodeListScriptPolicyRequest(request, r); err != nil {
return res, errors.Wrap(err, "encode request")
}
{
type bitset = [1]uint8
@@ -2077,222 +2314,17 @@ func (c *Client) sendListScriptPolicy(ctx context.Context, params ListScriptPoli
return result, nil
}
// ListScripts invokes listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
func (c *Client) ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error) {
res, err := c.sendListScripts(ctx, params)
return res, err
}
func (c *Client) sendListScripts(ctx context.Context, params ListScriptsParams) (res []Script, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listScripts"),
semconv.HTTPRequestMethodKey.String("GET"),
semconv.HTTPRouteKey.String("/scripts"),
}
// Run stopwatch.
startTime := time.Now()
defer func() {
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedDuration := time.Since(startTime)
c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...))
}()
// Increment request counter.
c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
// Start a span for this request.
ctx, span := c.cfg.Tracer.Start(ctx, ListScriptsOperation,
trace.WithAttributes(otelAttrs...),
clientSpanKind,
)
// Track stage for error reporting.
var stage string
defer func() {
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, stage)
c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...))
}
span.End()
}()
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [1]string
pathParts[0] = "/scripts"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeQueryParams"
q := uri.NewQueryEncoder()
{
// Encode "Page" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Page",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Page))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Limit" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Limit",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Limit))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Hash" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Hash",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.Hash.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Name" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Name",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.Name.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Source" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Source",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.Source.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "SubmissionID" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "SubmissionID",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.SubmissionID.Get(); ok {
return e.EncodeValue(conv.Int64ToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
u.RawQuery = q.Values().Encode()
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "GET", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
{
type bitset = [1]uint8
var satisfied bitset
{
stage = "Security:CookieAuth"
switch err := c.securityCookieAuth(ctx, ListScriptsOperation, r); {
case err == nil: // if NO error
satisfied[0] |= 1 << 0
case errors.Is(err, ogenerrors.ErrSkipClientSecurity):
// Skip this security.
default:
return res, errors.Wrap(err, "security \"CookieAuth\"")
}
}
if ok := func() bool {
nextRequirement:
for _, requirement := range []bitset{
{0b00000001},
} {
for i, mask := range requirement {
if satisfied[i]&mask != mask {
continue nextRequirement
}
}
return true
}
return false
}(); !ok {
return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied
}
}
stage = "SendRequest"
resp, err := c.cfg.Client.Do(r)
if err != nil {
return res, errors.Wrap(err, "do request")
}
defer resp.Body.Close()
stage = "DecodeResponse"
result, err := decodeListScriptsResponse(resp)
if err != nil {
return res, errors.Wrap(err, "decode response")
}
return result, nil
}
// ListSubmissions invokes listSubmissions operation.
//
// Get list of submissions.
//
// GET /submissions
func (c *Client) ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error) {
res, err := c.sendListSubmissions(ctx, params)
func (c *Client) ListSubmissions(ctx context.Context, request *ListSubmissionsReq) ([]Submission, error) {
res, err := c.sendListSubmissions(ctx, request)
return res, err
}
func (c *Client) sendListSubmissions(ctx context.Context, params ListSubmissionsParams) (res []Submission, err error) {
func (c *Client) sendListSubmissions(ctx context.Context, request *ListSubmissionsReq) (res []Submission, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("listSubmissions"),
semconv.HTTPRequestMethodKey.String("GET"),
@@ -2332,94 +2364,14 @@ func (c *Client) sendListSubmissions(ctx context.Context, params ListSubmissions
pathParts[0] = "/submissions"
uri.AddPathParts(u, pathParts[:]...)
stage = "EncodeQueryParams"
q := uri.NewQueryEncoder()
{
// Encode "Page" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Page",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Page))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Limit" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Limit",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
return e.EncodeValue(conv.Int32ToString(params.Limit))
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "DisplayName" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "DisplayName",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.DisplayName.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "Creator" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "Creator",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.Creator.Get(); ok {
return e.EncodeValue(conv.StringToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
{
// Encode "GameID" parameter.
cfg := uri.QueryParameterEncodingConfig{
Name: "GameID",
Style: uri.QueryStyleForm,
Explode: true,
}
if err := q.EncodeParam(cfg, func(e uri.Encoder) error {
if val, ok := params.GameID.Get(); ok {
return e.EncodeValue(conv.Int32ToString(val))
}
return nil
}); err != nil {
return res, errors.Wrap(err, "encode query")
}
}
u.RawQuery = q.Values().Encode()
stage = "EncodeRequest"
r, err := ht.NewRequest(ctx, "GET", u)
if err != nil {
return res, errors.Wrap(err, "create request")
}
if err := encodeListSubmissionsRequest(request, r); err != nil {
return res, errors.Wrap(err, "encode request")
}
{
type bitset = [1]uint8
@@ -2724,7 +2676,7 @@ func (c *Client) sendUpdateScript(ctx context.Context, request *ScriptUpdate, pa
//
// Update the specified script policy by ID.
//
// POST /script-policy/{ScriptPolicyID}
// POST /script-policy/id/{ScriptPolicyID}
func (c *Client) UpdateScriptPolicy(ctx context.Context, request *ScriptPolicyUpdate, params UpdateScriptPolicyParams) error {
_, err := c.sendUpdateScriptPolicy(ctx, request, params)
return err
@@ -2734,7 +2686,7 @@ func (c *Client) sendUpdateScriptPolicy(ctx context.Context, request *ScriptPoli
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("updateScriptPolicy"),
semconv.HTTPRequestMethodKey.String("POST"),
semconv.HTTPRouteKey.String("/script-policy/{ScriptPolicyID}"),
semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"),
}
// Run stopwatch.
@@ -2767,7 +2719,7 @@ func (c *Client) sendUpdateScriptPolicy(ctx context.Context, request *ScriptPoli
stage = "BuildURL"
u := uri.Clone(c.requestURL(ctx))
var pathParts [2]string
pathParts[0] = "/script-policy/"
pathParts[0] = "/script-policy/id/"
{
// Encode "ScriptPolicyID" parameter.
e := uri.NewPathEncoder(uri.PathEncoderConfig{

File diff suppressed because it is too large Load Diff

View File

@@ -221,6 +221,228 @@ func (s *ID) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ListScriptPolicyReq) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ListScriptPolicyReq) encodeFields(e *jx.Encoder) {
{
e.FieldStart("Page")
s.Page.Encode(e)
}
{
if s.Filter.Set {
e.FieldStart("Filter")
s.Filter.Encode(e)
}
}
}
var jsonFieldsNameOfListScriptPolicyReq = [2]string{
0: "Page",
1: "Filter",
}
// Decode decodes ListScriptPolicyReq from json.
func (s *ListScriptPolicyReq) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ListScriptPolicyReq to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "Page":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Page.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Page\"")
}
case "Filter":
if err := func() error {
s.Filter.Reset()
if err := s.Filter.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Filter\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ListScriptPolicyReq")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfListScriptPolicyReq) {
name = jsonFieldsNameOfListScriptPolicyReq[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 *ListScriptPolicyReq) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ListScriptPolicyReq) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ListSubmissionsReq) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ListSubmissionsReq) encodeFields(e *jx.Encoder) {
{
e.FieldStart("Page")
s.Page.Encode(e)
}
{
if s.Filter.Set {
e.FieldStart("Filter")
s.Filter.Encode(e)
}
}
}
var jsonFieldsNameOfListSubmissionsReq = [2]string{
0: "Page",
1: "Filter",
}
// Decode decodes ListSubmissionsReq from json.
func (s *ListSubmissionsReq) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ListSubmissionsReq to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "Page":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Page.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Page\"")
}
case "Filter":
if err := func() error {
s.Filter.Reset()
if err := s.Filter.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Filter\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ListSubmissionsReq")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfListSubmissionsReq) {
name = jsonFieldsNameOfListSubmissionsReq[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 *ListSubmissionsReq) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ListSubmissionsReq) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes int32 as json.
func (o OptInt32) Encode(e *jx.Encoder) {
if !o.Set {
@@ -291,6 +513,39 @@ func (s *OptInt64) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode encodes ScriptPolicyFilter as json.
func (o OptScriptPolicyFilter) Encode(e *jx.Encoder) {
if !o.Set {
return
}
o.Value.Encode(e)
}
// Decode decodes ScriptPolicyFilter from json.
func (o *OptScriptPolicyFilter) Decode(d *jx.Decoder) error {
if o == nil {
return errors.New("invalid: unable to decode OptScriptPolicyFilter to nil")
}
o.Set = true
if err := o.Value.Decode(d); err != nil {
return err
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s OptScriptPolicyFilter) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *OptScriptPolicyFilter) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes string as json.
func (o OptString) Encode(e *jx.Encoder) {
if !o.Set {
@@ -326,6 +581,152 @@ func (s *OptString) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode encodes SubmissionFilter as json.
func (o OptSubmissionFilter) Encode(e *jx.Encoder) {
if !o.Set {
return
}
o.Value.Encode(e)
}
// Decode decodes SubmissionFilter from json.
func (o *OptSubmissionFilter) Decode(d *jx.Decoder) error {
if o == nil {
return errors.New("invalid: unable to decode OptSubmissionFilter to nil")
}
o.Set = true
if err := o.Value.Decode(d); err != nil {
return err
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s OptSubmissionFilter) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *OptSubmissionFilter) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *Pagination) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *Pagination) encodeFields(e *jx.Encoder) {
{
e.FieldStart("Page")
e.Int32(s.Page)
}
{
e.FieldStart("Limit")
e.Int32(s.Limit)
}
}
var jsonFieldsNameOfPagination = [2]string{
0: "Page",
1: "Limit",
}
// Decode decodes Pagination from json.
func (s *Pagination) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode Pagination to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "Page":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Int32()
s.Page = int32(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Page\"")
}
case "Limit":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Int32()
s.Limit = int32(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Limit\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode Pagination")
}
// 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(jsonFieldsNameOfPagination) {
name = jsonFieldsNameOfPagination[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 *Pagination) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *Pagination) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *Script) Encode(e *jx.Encoder) {
e.ObjStart()
@@ -339,10 +740,6 @@ func (s *Script) encodeFields(e *jx.Encoder) {
e.FieldStart("ID")
e.Int64(s.ID)
}
{
e.FieldStart("Name")
e.Str(s.Name)
}
{
e.FieldStart("Hash")
e.Str(s.Hash)
@@ -357,12 +754,11 @@ func (s *Script) encodeFields(e *jx.Encoder) {
}
}
var jsonFieldsNameOfScript = [5]string{
var jsonFieldsNameOfScript = [4]string{
0: "ID",
1: "Name",
2: "Hash",
3: "Source",
4: "SubmissionID",
1: "Hash",
2: "Source",
3: "SubmissionID",
}
// Decode decodes Script from json.
@@ -386,20 +782,8 @@ func (s *Script) Decode(d *jx.Decoder) error {
}(); err != nil {
return errors.Wrap(err, "decode field \"ID\"")
}
case "Name":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Name = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Name\"")
}
case "Hash":
requiredBitSet[0] |= 1 << 2
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Hash = string(v)
@@ -411,7 +795,7 @@ func (s *Script) Decode(d *jx.Decoder) error {
return errors.Wrap(err, "decode field \"Hash\"")
}
case "Source":
requiredBitSet[0] |= 1 << 3
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Str()
s.Source = string(v)
@@ -423,7 +807,7 @@ func (s *Script) Decode(d *jx.Decoder) error {
return errors.Wrap(err, "decode field \"Source\"")
}
case "SubmissionID":
requiredBitSet[0] |= 1 << 4
requiredBitSet[0] |= 1 << 3
if err := func() error {
v, err := d.Int64()
s.SubmissionID = int64(v)
@@ -444,7 +828,7 @@ func (s *Script) Decode(d *jx.Decoder) error {
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00011111,
0b00001111,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
@@ -499,10 +883,6 @@ func (s *ScriptCreate) Encode(e *jx.Encoder) {
// encodeFields encodes fields.
func (s *ScriptCreate) encodeFields(e *jx.Encoder) {
{
e.FieldStart("Name")
e.Str(s.Name)
}
{
e.FieldStart("Source")
e.Str(s.Source)
@@ -515,10 +895,9 @@ func (s *ScriptCreate) encodeFields(e *jx.Encoder) {
}
}
var jsonFieldsNameOfScriptCreate = [3]string{
0: "Name",
1: "Source",
2: "SubmissionID",
var jsonFieldsNameOfScriptCreate = [2]string{
0: "Source",
1: "SubmissionID",
}
// Decode decodes ScriptCreate from json.
@@ -530,20 +909,8 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "Name":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Str()
s.Name = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Name\"")
}
case "Source":
requiredBitSet[0] |= 1 << 1
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Str()
s.Source = string(v)
@@ -574,7 +941,7 @@ func (s *ScriptCreate) Decode(d *jx.Decoder) error {
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000011,
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
@@ -897,6 +1264,120 @@ func (s *ScriptPolicyCreate) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ScriptPolicyFilter) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ScriptPolicyFilter) encodeFields(e *jx.Encoder) {
{
if s.ID.Set {
e.FieldStart("ID")
s.ID.Encode(e)
}
}
{
if s.FromScriptHash.Set {
e.FieldStart("FromScriptHash")
s.FromScriptHash.Encode(e)
}
}
{
if s.ToScriptID.Set {
e.FieldStart("ToScriptID")
s.ToScriptID.Encode(e)
}
}
{
if s.Policy.Set {
e.FieldStart("Policy")
s.Policy.Encode(e)
}
}
}
var jsonFieldsNameOfScriptPolicyFilter = [4]string{
0: "ID",
1: "FromScriptHash",
2: "ToScriptID",
3: "Policy",
}
// Decode decodes ScriptPolicyFilter from json.
func (s *ScriptPolicyFilter) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ScriptPolicyFilter to nil")
}
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "ID":
if err := func() error {
s.ID.Reset()
if err := s.ID.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"ID\"")
}
case "FromScriptHash":
if err := func() error {
s.FromScriptHash.Reset()
if err := s.FromScriptHash.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"FromScriptHash\"")
}
case "ToScriptID":
if err := func() error {
s.ToScriptID.Reset()
if err := s.ToScriptID.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"ToScriptID\"")
}
case "Policy":
if err := func() error {
s.Policy.Reset()
if err := s.Policy.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Policy\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ScriptPolicyFilter")
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *ScriptPolicyFilter) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ScriptPolicyFilter) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ScriptPolicyUpdate) Encode(e *jx.Encoder) {
e.ObjStart()
@@ -1057,12 +1538,6 @@ func (s *ScriptUpdate) encodeFields(e *jx.Encoder) {
e.FieldStart("ID")
e.Int64(s.ID)
}
{
if s.Name.Set {
e.FieldStart("Name")
s.Name.Encode(e)
}
}
{
if s.Source.Set {
e.FieldStart("Source")
@@ -1077,11 +1552,10 @@ func (s *ScriptUpdate) encodeFields(e *jx.Encoder) {
}
}
var jsonFieldsNameOfScriptUpdate = [4]string{
var jsonFieldsNameOfScriptUpdate = [3]string{
0: "ID",
1: "Name",
2: "Source",
3: "SubmissionID",
1: "Source",
2: "SubmissionID",
}
// Decode decodes ScriptUpdate from json.
@@ -1105,16 +1579,6 @@ func (s *ScriptUpdate) Decode(d *jx.Decoder) error {
}(); err != nil {
return errors.Wrap(err, "decode field \"ID\"")
}
case "Name":
if err := func() error {
s.Name.Reset()
if err := s.Name.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Name\"")
}
case "Source":
if err := func() error {
s.Source.Reset()
@@ -1672,3 +2136,150 @@ func (s *SubmissionCreate) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *SubmissionFilter) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *SubmissionFilter) encodeFields(e *jx.Encoder) {
{
e.FieldStart("ID")
e.Int64(s.ID)
}
{
if s.DisplayName.Set {
e.FieldStart("DisplayName")
s.DisplayName.Encode(e)
}
}
{
if s.Creator.Set {
e.FieldStart("Creator")
s.Creator.Encode(e)
}
}
{
if s.GameID.Set {
e.FieldStart("GameID")
s.GameID.Encode(e)
}
}
}
var jsonFieldsNameOfSubmissionFilter = [4]string{
0: "ID",
1: "DisplayName",
2: "Creator",
3: "GameID",
}
// Decode decodes SubmissionFilter from json.
func (s *SubmissionFilter) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode SubmissionFilter 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 "DisplayName":
if err := func() error {
s.DisplayName.Reset()
if err := s.DisplayName.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"DisplayName\"")
}
case "Creator":
if err := func() error {
s.Creator.Reset()
if err := s.Creator.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Creator\"")
}
case "GameID":
if err := func() error {
s.GameID.Reset()
if err := s.GameID.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"GameID\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode SubmissionFilter")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfSubmissionFilter) {
name = jsonFieldsNameOfSubmissionFilter[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 *SubmissionFilter) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *SubmissionFilter) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}

View File

@@ -6,12 +6,14 @@ package api
type OperationName = string
const (
ActionSubmissionPublishOperation OperationName = "ActionSubmissionPublish"
ActionSubmissionRejectOperation OperationName = "ActionSubmissionReject"
ActionSubmissionRequestChangesOperation OperationName = "ActionSubmissionRequestChanges"
ActionSubmissionRevokeOperation OperationName = "ActionSubmissionRevoke"
ActionSubmissionSubmitOperation OperationName = "ActionSubmissionSubmit"
ActionSubmissionTriggerUploadOperation OperationName = "ActionSubmissionTriggerUpload"
ActionSubmissionTriggerPublishOperation OperationName = "ActionSubmissionTriggerPublish"
ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate"
ActionSubmissionValidateOperation OperationName = "ActionSubmissionValidate"
CreateScriptOperation OperationName = "CreateScript"
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
CreateSubmissionOperation OperationName = "CreateSubmission"
@@ -19,9 +21,9 @@ const (
DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy"
GetScriptOperation OperationName = "GetScript"
GetScriptPolicyOperation OperationName = "GetScriptPolicy"
GetScriptPolicyFromHashOperation OperationName = "GetScriptPolicyFromHash"
GetSubmissionOperation OperationName = "GetSubmission"
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
ListScriptsOperation OperationName = "ListScripts"
ListSubmissionsOperation OperationName = "ListSubmissions"
SetSubmissionCompletedOperation OperationName = "SetSubmissionCompleted"
UpdateScriptOperation OperationName = "UpdateScript"

File diff suppressed because it is too large Load Diff

View File

@@ -220,6 +220,148 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) (
}
}
func (s *Server) decodeListScriptPolicyRequest(r *http.Request) (
req *ListScriptPolicyReq,
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 ListScriptPolicyReq
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) decodeListSubmissionsRequest(r *http.Request) (
req *ListSubmissionsReq,
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 ListSubmissionsReq
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) decodeUpdateScriptRequest(r *http.Request) (
req *ScriptUpdate,
close func() error,

View File

@@ -53,6 +53,34 @@ func encodeCreateSubmissionRequest(
return nil
}
func encodeListScriptPolicyRequest(
req *ListScriptPolicyReq,
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 encodeListSubmissionsRequest(
req *ListSubmissionsReq,
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 encodeUpdateScriptRequest(
req *ScriptUpdate,
r *http.Request,

View File

@@ -15,6 +15,57 @@ import (
"github.com/ogen-go/ogen/validate"
)
func decodeActionSubmissionPublishResponse(resp *http.Response) (res *ActionSubmissionPublishNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionPublishNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionRejectResponse(resp *http.Response) (res *ActionSubmissionRejectNoContent, _ error) {
switch resp.StatusCode {
case 204:
@@ -219,11 +270,11 @@ func decodeActionSubmissionSubmitResponse(resp *http.Response) (res *ActionSubmi
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionTriggerUploadResponse(resp *http.Response) (res *ActionSubmissionTriggerUploadNoContent, _ error) {
func decodeActionSubmissionTriggerPublishResponse(resp *http.Response) (res *ActionSubmissionTriggerPublishNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionTriggerUploadNoContent{}, nil
return &ActionSubmissionTriggerPublishNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
@@ -321,6 +372,57 @@ func decodeActionSubmissionTriggerValidateResponse(resp *http.Response) (res *Ac
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionValidateResponse(resp *http.Response) (res *ActionSubmissionValidateNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionValidateNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeCreateScriptResponse(resp *http.Response) (res *ID, _ error) {
switch resp.StatusCode {
case 201:
@@ -856,6 +958,98 @@ func decodeGetScriptPolicyResponse(resp *http.Response) (res *ScriptPolicy, _ er
return res, errors.Wrap(defRes, "error")
}
func decodeGetScriptPolicyFromHashResponse(resp *http.Response) (res *ScriptPolicy, _ error) {
switch resp.StatusCode {
case 200:
// Code 200.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response ScriptPolicy
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if err := response.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return &response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeGetSubmissionResponse(resp *http.Response) (res *Submission, _ error) {
switch resp.StatusCode {
case 200:
@@ -1065,123 +1259,6 @@ func decodeListScriptPolicyResponse(resp *http.Response) (res []ScriptPolicy, _
return res, errors.Wrap(defRes, "error")
}
func decodeListScriptsResponse(resp *http.Response) (res []Script, _ error) {
switch resp.StatusCode {
case 200:
// Code 200.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response []Script
if err := func() error {
response = make([]Script, 0)
if err := d.Arr(func(d *jx.Decoder) error {
var elem Script
if err := elem.Decode(d); err != nil {
return err
}
response = append(response, elem)
return nil
}); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if response == nil {
return errors.New("nil is invalid value")
}
var failures []validate.FieldError
for i, elem := range response {
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
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeListSubmissionsResponse(resp *http.Response) (res []Submission, _ error) {
switch resp.StatusCode {
case 200:

View File

@@ -13,6 +13,13 @@ import (
ht "github.com/ogen-go/ogen/http"
)
func encodeActionSubmissionPublishResponse(response *ActionSubmissionPublishNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionRejectResponse(response *ActionSubmissionRejectNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
@@ -41,7 +48,7 @@ func encodeActionSubmissionSubmitResponse(response *ActionSubmissionSubmitNoCont
return nil
}
func encodeActionSubmissionTriggerUploadResponse(response *ActionSubmissionTriggerUploadNoContent, w http.ResponseWriter, span trace.Span) error {
func encodeActionSubmissionTriggerPublishResponse(response *ActionSubmissionTriggerPublishNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
@@ -55,6 +62,13 @@ func encodeActionSubmissionTriggerValidateResponse(response *ActionSubmissionTri
return nil
}
func encodeActionSubmissionValidateResponse(response *ActionSubmissionValidateNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeCreateScriptResponse(response *ID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
@@ -139,6 +153,20 @@ func encodeGetScriptPolicyResponse(response *ScriptPolicy, w http.ResponseWriter
return nil
}
func encodeGetScriptPolicyFromHashResponse(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)
response.Encode(e)
if _, err := e.WriteTo(w); err != nil {
return errors.Wrap(err, "write")
}
return nil
}
func encodeGetSubmissionResponse(response *Submission, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)
@@ -171,24 +199,6 @@ func encodeListScriptPolicyResponse(response []ScriptPolicy, w http.ResponseWrit
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 encodeListSubmissionsResponse(response []Submission, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(200)

View File

@@ -102,31 +102,74 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
break
}
// Param: "ScriptPolicyID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "DELETE":
s.handleDeleteScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
case "GET":
s.handleGetScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
case "POST":
s.handleUpdateScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "DELETE,GET,POST")
break
}
switch elem[0] {
case 'h': // Prefix: "hash/"
origElem := elem
if l := len("hash/"); len(elem) >= l && elem[0:l] == "hash/" {
elem = elem[l:]
} else {
break
}
return
// Param: "FromScriptHash"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "GET":
s.handleGetScriptPolicyFromHashRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "GET")
}
return
}
elem = origElem
case 'i': // Prefix: "id/"
origElem := elem
if l := len("id/"); len(elem) >= l && elem[0:l] == "id/" {
elem = elem[l:]
} else {
break
}
// Param: "ScriptPolicyID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "DELETE":
s.handleDeleteScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
case "GET":
s.handleGetScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
case "POST":
s.handleUpdateScriptPolicyRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "DELETE,GET,POST")
}
return
}
elem = origElem
}
elem = origElem
@@ -143,12 +186,10 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(elem) == 0 {
switch r.Method {
case "GET":
s.handleListScriptsRequest([0]string{}, elemIsEscaped, w, r)
case "POST":
s.handleCreateScriptRequest([0]string{}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "GET,POST")
s.notAllowed(w, r, "POST")
}
return
@@ -436,9 +477,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
break
}
switch elem[0] {
case 'u': // Prefix: "upload"
case 'p': // Prefix: "publish"
origElem := elem
if l := len("upload"); len(elem) >= l && elem[0:l] == "upload" {
if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" {
elem = elem[l:]
} else {
break
@@ -448,7 +489,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionTriggerUploadRequest([1]string{
s.handleActionSubmissionTriggerPublishRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
@@ -484,6 +525,67 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
elem = origElem
}
elem = origElem
case 'v': // Prefix: "validator-"
origElem := elem
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'p': // Prefix: "published"
origElem := elem
if l := len("published"); len(elem) >= l && elem[0:l] == "published" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionPublishRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
case 'v': // Prefix: "validated"
origElem := elem
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionValidateRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
}
elem = origElem
}
@@ -643,41 +745,86 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
break
}
// Param: "ScriptPolicyID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch method {
case "DELETE":
r.name = DeleteScriptPolicyOperation
r.summary = "Delete the specified script policy by ID"
r.operationID = "deleteScriptPolicy"
r.pathPattern = "/script-policy/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
case "GET":
r.name = GetScriptPolicyOperation
r.summary = "Get the specified script policy by ID"
r.operationID = "getScriptPolicy"
r.pathPattern = "/script-policy/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
case "POST":
r.name = UpdateScriptPolicyOperation
r.summary = "Update the specified script policy by ID"
r.operationID = "updateScriptPolicy"
r.pathPattern = "/script-policy/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
default:
return
break
}
switch elem[0] {
case 'h': // Prefix: "hash/"
origElem := elem
if l := len("hash/"); len(elem) >= l && elem[0:l] == "hash/" {
elem = elem[l:]
} else {
break
}
// Param: "FromScriptHash"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch method {
case "GET":
r.name = GetScriptPolicyFromHashOperation
r.summary = "Get the policy for the given hash of script source code"
r.operationID = "getScriptPolicyFromHash"
r.pathPattern = "/script-policy/hash/{FromScriptHash}"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 'i': // Prefix: "id/"
origElem := elem
if l := len("id/"); len(elem) >= l && elem[0:l] == "id/" {
elem = elem[l:]
} else {
break
}
// Param: "ScriptPolicyID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch method {
case "DELETE":
r.name = DeleteScriptPolicyOperation
r.summary = "Delete the specified script policy by ID"
r.operationID = "deleteScriptPolicy"
r.pathPattern = "/script-policy/id/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
case "GET":
r.name = GetScriptPolicyOperation
r.summary = "Get the specified script policy by ID"
r.operationID = "getScriptPolicy"
r.pathPattern = "/script-policy/id/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
case "POST":
r.name = UpdateScriptPolicyOperation
r.summary = "Update the specified script policy by ID"
r.operationID = "updateScriptPolicy"
r.pathPattern = "/script-policy/id/{ScriptPolicyID}"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
}
elem = origElem
@@ -694,14 +841,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
if len(elem) == 0 {
switch method {
case "GET":
r.name = ListScriptsOperation
r.summary = "Get list of scripts"
r.operationID = "listScripts"
r.pathPattern = "/scripts"
r.args = args
r.count = 0
return r, true
case "POST":
r.name = CreateScriptOperation
r.summary = "Create a new script"
@@ -1031,9 +1170,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
break
}
switch elem[0] {
case 'u': // Prefix: "upload"
case 'p': // Prefix: "publish"
origElem := elem
if l := len("upload"); len(elem) >= l && elem[0:l] == "upload" {
if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" {
elem = elem[l:]
} else {
break
@@ -1043,10 +1182,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionTriggerUploadOperation
r.summary = "Role Admin changes status from Validated -> Uploading"
r.operationID = "actionSubmissionTriggerUpload"
r.pathPattern = "/submissions/{SubmissionID}/status/trigger-upload"
r.name = ActionSubmissionTriggerPublishOperation
r.summary = "Role Admin changes status from Validated -> Publishing"
r.operationID = "actionSubmissionTriggerPublish"
r.pathPattern = "/submissions/{SubmissionID}/status/trigger-publish"
r.args = args
r.count = 1
return r, true
@@ -1083,6 +1222,71 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
elem = origElem
}
elem = origElem
case 'v': // Prefix: "validator-"
origElem := elem
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'p': // Prefix: "published"
origElem := elem
if l := len("published"); len(elem) >= l && elem[0:l] == "published" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionPublishOperation
r.summary = "(Internal endpoint) Role Validator changes status from Publishing -> Published"
r.operationID = "actionSubmissionPublish"
r.pathPattern = "/submissions/{SubmissionID}/status/validator-published"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 'v': // Prefix: "validated"
origElem := elem
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionValidateOperation
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Validated"
r.operationID = "actionSubmissionValidate"
r.pathPattern = "/submissions/{SubmissionID}/status/validator-validated"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
}
elem = origElem
}

View File

@@ -10,6 +10,9 @@ func (s *ErrorStatusCode) Error() string {
return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response)
}
// ActionSubmissionPublishNoContent is response for ActionSubmissionPublish operation.
type ActionSubmissionPublishNoContent struct{}
// ActionSubmissionRejectNoContent is response for ActionSubmissionReject operation.
type ActionSubmissionRejectNoContent struct{}
@@ -22,12 +25,15 @@ type ActionSubmissionRevokeNoContent struct{}
// ActionSubmissionSubmitNoContent is response for ActionSubmissionSubmit operation.
type ActionSubmissionSubmitNoContent struct{}
// ActionSubmissionTriggerUploadNoContent is response for ActionSubmissionTriggerUpload operation.
type ActionSubmissionTriggerUploadNoContent struct{}
// ActionSubmissionTriggerPublishNoContent is response for ActionSubmissionTriggerPublish operation.
type ActionSubmissionTriggerPublishNoContent struct{}
// ActionSubmissionTriggerValidateNoContent is response for ActionSubmissionTriggerValidate operation.
type ActionSubmissionTriggerValidateNoContent struct{}
// ActionSubmissionValidateNoContent is response for ActionSubmissionValidate operation.
type ActionSubmissionValidateNoContent struct{}
type CookieAuth struct {
APIKey string
}
@@ -116,6 +122,56 @@ func (s *ID) SetID(val int64) {
s.ID = val
}
type ListScriptPolicyReq struct {
Page Pagination `json:"Page"`
Filter OptScriptPolicyFilter `json:"Filter"`
}
// GetPage returns the value of Page.
func (s *ListScriptPolicyReq) GetPage() Pagination {
return s.Page
}
// GetFilter returns the value of Filter.
func (s *ListScriptPolicyReq) GetFilter() OptScriptPolicyFilter {
return s.Filter
}
// SetPage sets the value of Page.
func (s *ListScriptPolicyReq) SetPage(val Pagination) {
s.Page = val
}
// SetFilter sets the value of Filter.
func (s *ListScriptPolicyReq) SetFilter(val OptScriptPolicyFilter) {
s.Filter = val
}
type ListSubmissionsReq struct {
Page Pagination `json:"Page"`
Filter OptSubmissionFilter `json:"Filter"`
}
// GetPage returns the value of Page.
func (s *ListSubmissionsReq) GetPage() Pagination {
return s.Page
}
// GetFilter returns the value of Filter.
func (s *ListSubmissionsReq) GetFilter() OptSubmissionFilter {
return s.Filter
}
// SetPage sets the value of Page.
func (s *ListSubmissionsReq) SetPage(val Pagination) {
s.Page = val
}
// SetFilter sets the value of Filter.
func (s *ListSubmissionsReq) SetFilter(val OptSubmissionFilter) {
s.Filter = val
}
// NewOptInt32 returns new OptInt32 with value set to v.
func NewOptInt32(v int32) OptInt32 {
return OptInt32{
@@ -208,6 +264,52 @@ func (o OptInt64) Or(d int64) int64 {
return d
}
// NewOptScriptPolicyFilter returns new OptScriptPolicyFilter with value set to v.
func NewOptScriptPolicyFilter(v ScriptPolicyFilter) OptScriptPolicyFilter {
return OptScriptPolicyFilter{
Value: v,
Set: true,
}
}
// OptScriptPolicyFilter is optional ScriptPolicyFilter.
type OptScriptPolicyFilter struct {
Value ScriptPolicyFilter
Set bool
}
// IsSet returns true if OptScriptPolicyFilter was set.
func (o OptScriptPolicyFilter) IsSet() bool { return o.Set }
// Reset unsets value.
func (o *OptScriptPolicyFilter) Reset() {
var v ScriptPolicyFilter
o.Value = v
o.Set = false
}
// SetTo sets value to v.
func (o *OptScriptPolicyFilter) SetTo(v ScriptPolicyFilter) {
o.Set = true
o.Value = v
}
// Get returns value and boolean that denotes whether value was set.
func (o OptScriptPolicyFilter) Get() (v ScriptPolicyFilter, 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 OptScriptPolicyFilter) Or(d ScriptPolicyFilter) ScriptPolicyFilter {
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{
@@ -254,10 +356,81 @@ func (o OptString) Or(d string) string {
return d
}
// NewOptSubmissionFilter returns new OptSubmissionFilter with value set to v.
func NewOptSubmissionFilter(v SubmissionFilter) OptSubmissionFilter {
return OptSubmissionFilter{
Value: v,
Set: true,
}
}
// OptSubmissionFilter is optional SubmissionFilter.
type OptSubmissionFilter struct {
Value SubmissionFilter
Set bool
}
// IsSet returns true if OptSubmissionFilter was set.
func (o OptSubmissionFilter) IsSet() bool { return o.Set }
// Reset unsets value.
func (o *OptSubmissionFilter) Reset() {
var v SubmissionFilter
o.Value = v
o.Set = false
}
// SetTo sets value to v.
func (o *OptSubmissionFilter) SetTo(v SubmissionFilter) {
o.Set = true
o.Value = v
}
// Get returns value and boolean that denotes whether value was set.
func (o OptSubmissionFilter) Get() (v SubmissionFilter, 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 OptSubmissionFilter) Or(d SubmissionFilter) SubmissionFilter {
if v, ok := o.Get(); ok {
return v
}
return d
}
// Ref: #/components/schemas/Pagination
type Pagination struct {
Page int32 `json:"Page"`
Limit int32 `json:"Limit"`
}
// GetPage returns the value of Page.
func (s *Pagination) GetPage() int32 {
return s.Page
}
// GetLimit returns the value of Limit.
func (s *Pagination) GetLimit() int32 {
return s.Limit
}
// SetPage sets the value of Page.
func (s *Pagination) SetPage(val int32) {
s.Page = val
}
// SetLimit sets the value of Limit.
func (s *Pagination) SetLimit(val int32) {
s.Limit = val
}
// Ref: #/components/schemas/Script
type Script struct {
ID int64 `json:"ID"`
Name string `json:"Name"`
Hash string `json:"Hash"`
Source string `json:"Source"`
SubmissionID int64 `json:"SubmissionID"`
@@ -268,11 +441,6 @@ 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
@@ -293,11 +461,6 @@ 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
@@ -315,16 +478,10 @@ func (s *Script) SetSubmissionID(val int64) {
// Ref: #/components/schemas/ScriptCreate
type ScriptCreate struct {
Name string `json:"Name"`
Source string `json:"Source"`
SubmissionID OptInt64 `json:"SubmissionID"`
}
// 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
@@ -335,11 +492,6 @@ func (s *ScriptCreate) GetSubmissionID() OptInt64 {
return s.SubmissionID
}
// 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
@@ -435,6 +587,54 @@ func (s *ScriptPolicyCreate) SetPolicy(val int32) {
s.Policy = val
}
// Ref: #/components/schemas/ScriptPolicyFilter
type ScriptPolicyFilter struct {
ID OptInt64 `json:"ID"`
FromScriptHash OptString `json:"FromScriptHash"`
ToScriptID OptInt64 `json:"ToScriptID"`
Policy OptInt32 `json:"Policy"`
}
// GetID returns the value of ID.
func (s *ScriptPolicyFilter) GetID() OptInt64 {
return s.ID
}
// GetFromScriptHash returns the value of FromScriptHash.
func (s *ScriptPolicyFilter) GetFromScriptHash() OptString {
return s.FromScriptHash
}
// GetToScriptID returns the value of ToScriptID.
func (s *ScriptPolicyFilter) GetToScriptID() OptInt64 {
return s.ToScriptID
}
// GetPolicy returns the value of Policy.
func (s *ScriptPolicyFilter) GetPolicy() OptInt32 {
return s.Policy
}
// SetID sets the value of ID.
func (s *ScriptPolicyFilter) SetID(val OptInt64) {
s.ID = val
}
// SetFromScriptHash sets the value of FromScriptHash.
func (s *ScriptPolicyFilter) SetFromScriptHash(val OptString) {
s.FromScriptHash = val
}
// SetToScriptID sets the value of ToScriptID.
func (s *ScriptPolicyFilter) SetToScriptID(val OptInt64) {
s.ToScriptID = val
}
// SetPolicy sets the value of Policy.
func (s *ScriptPolicyFilter) SetPolicy(val OptInt32) {
s.Policy = val
}
// Ref: #/components/schemas/ScriptPolicyUpdate
type ScriptPolicyUpdate struct {
ID int64 `json:"ID"`
@@ -486,7 +686,6 @@ func (s *ScriptPolicyUpdate) SetPolicy(val OptInt32) {
// Ref: #/components/schemas/ScriptUpdate
type ScriptUpdate struct {
ID int64 `json:"ID"`
Name OptString `json:"Name"`
Source OptString `json:"Source"`
SubmissionID OptInt64 `json:"SubmissionID"`
}
@@ -496,11 +695,6 @@ func (s *ScriptUpdate) GetID() int64 {
return s.ID
}
// GetName returns the value of Name.
func (s *ScriptUpdate) GetName() OptString {
return s.Name
}
// GetSource returns the value of Source.
func (s *ScriptUpdate) GetSource() OptString {
return s.Source
@@ -516,11 +710,6 @@ func (s *ScriptUpdate) SetID(val int64) {
s.ID = val
}
// SetName sets the value of Name.
func (s *ScriptUpdate) SetName(val OptString) {
s.Name = val
}
// SetSource sets the value of Source.
func (s *ScriptUpdate) SetSource(val OptString) {
s.Source = val
@@ -751,6 +940,54 @@ func (s *SubmissionCreate) SetTargetAssetID(val OptInt64) {
s.TargetAssetID = val
}
// Ref: #/components/schemas/SubmissionFilter
type SubmissionFilter struct {
ID int64 `json:"ID"`
DisplayName OptString `json:"DisplayName"`
Creator OptString `json:"Creator"`
GameID OptInt32 `json:"GameID"`
}
// GetID returns the value of ID.
func (s *SubmissionFilter) GetID() int64 {
return s.ID
}
// GetDisplayName returns the value of DisplayName.
func (s *SubmissionFilter) GetDisplayName() OptString {
return s.DisplayName
}
// GetCreator returns the value of Creator.
func (s *SubmissionFilter) GetCreator() OptString {
return s.Creator
}
// GetGameID returns the value of GameID.
func (s *SubmissionFilter) GetGameID() OptInt32 {
return s.GameID
}
// SetID sets the value of ID.
func (s *SubmissionFilter) SetID(val int64) {
s.ID = val
}
// SetDisplayName sets the value of DisplayName.
func (s *SubmissionFilter) SetDisplayName(val OptString) {
s.DisplayName = val
}
// SetCreator sets the value of Creator.
func (s *SubmissionFilter) SetCreator(val OptString) {
s.Creator = val
}
// SetGameID sets the value of GameID.
func (s *SubmissionFilter) SetGameID(val OptInt32) {
s.GameID = val
}
// UpdateScriptNoContent is response for UpdateScript operation.
type UpdateScriptNoContent struct{}

View File

@@ -8,6 +8,12 @@ import (
// Handler handles operations described by OpenAPI v3 specification.
type Handler interface {
// ActionSubmissionPublish implements actionSubmissionPublish operation.
//
// (Internal endpoint) Role Validator changes status from Publishing -> Published.
//
// POST /submissions/{SubmissionID}/status/validator-published
ActionSubmissionPublish(ctx context.Context, params ActionSubmissionPublishParams) error
// ActionSubmissionReject implements actionSubmissionReject operation.
//
// Role Reviewer changes status from Submitted -> Rejected.
@@ -32,18 +38,24 @@ type Handler interface {
//
// POST /submissions/{SubmissionID}/status/submit
ActionSubmissionSubmit(ctx context.Context, params ActionSubmissionSubmitParams) error
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
// ActionSubmissionTriggerPublish implements actionSubmissionTriggerPublish operation.
//
// Role Admin changes status from Validated -> Uploading.
// Role Admin changes status from Validated -> Publishing.
//
// POST /submissions/{SubmissionID}/status/trigger-upload
ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error
// POST /submissions/{SubmissionID}/status/trigger-publish
ActionSubmissionTriggerPublish(ctx context.Context, params ActionSubmissionTriggerPublishParams) error
// ActionSubmissionTriggerValidate implements actionSubmissionTriggerValidate operation.
//
// Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating.
//
// POST /submissions/{SubmissionID}/status/trigger-validate
ActionSubmissionTriggerValidate(ctx context.Context, params ActionSubmissionTriggerValidateParams) error
// ActionSubmissionValidate implements actionSubmissionValidate operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error
// CreateScript implements createScript operation.
//
// Create a new script.
@@ -72,7 +84,7 @@ type Handler interface {
//
// Delete the specified script policy by ID.
//
// DELETE /script-policy/{ScriptPolicyID}
// DELETE /script-policy/id/{ScriptPolicyID}
DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error
// GetScript implements getScript operation.
//
@@ -84,8 +96,14 @@ type Handler interface {
//
// Get the specified script policy by ID.
//
// GET /script-policy/{ScriptPolicyID}
// GET /script-policy/id/{ScriptPolicyID}
GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error)
// GetScriptPolicyFromHash implements getScriptPolicyFromHash operation.
//
// Get the policy for the given hash of script source code.
//
// GET /script-policy/hash/{FromScriptHash}
GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error)
// GetSubmission implements getSubmission operation.
//
// Retrieve map with ID.
@@ -97,19 +115,13 @@ type Handler interface {
// 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)
ListScriptPolicy(ctx context.Context, req *ListScriptPolicyReq) ([]ScriptPolicy, error)
// ListSubmissions implements listSubmissions operation.
//
// Get list of submissions.
//
// GET /submissions
ListSubmissions(ctx context.Context, params ListSubmissionsParams) ([]Submission, error)
ListSubmissions(ctx context.Context, req *ListSubmissionsReq) ([]Submission, error)
// SetSubmissionCompleted implements setSubmissionCompleted operation.
//
// Retrieve map with ID.
@@ -126,7 +138,7 @@ type Handler interface {
//
// Update the specified script policy by ID.
//
// POST /script-policy/{ScriptPolicyID}
// POST /script-policy/id/{ScriptPolicyID}
UpdateScriptPolicy(ctx context.Context, req *ScriptPolicyUpdate, params UpdateScriptPolicyParams) error
// UpdateSubmissionModel implements updateSubmissionModel operation.
//

View File

@@ -13,6 +13,15 @@ type UnimplementedHandler struct{}
var _ Handler = UnimplementedHandler{}
// ActionSubmissionPublish implements actionSubmissionPublish operation.
//
// (Internal endpoint) Role Validator changes status from Publishing -> Published.
//
// POST /submissions/{SubmissionID}/status/validator-published
func (UnimplementedHandler) ActionSubmissionPublish(ctx context.Context, params ActionSubmissionPublishParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionReject implements actionSubmissionReject operation.
//
// Role Reviewer changes status from Submitted -> Rejected.
@@ -49,12 +58,12 @@ func (UnimplementedHandler) ActionSubmissionSubmit(ctx context.Context, params A
return ht.ErrNotImplemented
}
// ActionSubmissionTriggerUpload implements actionSubmissionTriggerUpload operation.
// ActionSubmissionTriggerPublish implements actionSubmissionTriggerPublish operation.
//
// Role Admin changes status from Validated -> Uploading.
// Role Admin changes status from Validated -> Publishing.
//
// POST /submissions/{SubmissionID}/status/trigger-upload
func (UnimplementedHandler) ActionSubmissionTriggerUpload(ctx context.Context, params ActionSubmissionTriggerUploadParams) error {
// POST /submissions/{SubmissionID}/status/trigger-publish
func (UnimplementedHandler) ActionSubmissionTriggerPublish(ctx context.Context, params ActionSubmissionTriggerPublishParams) error {
return ht.ErrNotImplemented
}
@@ -67,6 +76,15 @@ func (UnimplementedHandler) ActionSubmissionTriggerValidate(ctx context.Context,
return ht.ErrNotImplemented
}
// ActionSubmissionValidate implements actionSubmissionValidate operation.
//
// (Internal endpoint) Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validator-validated
func (UnimplementedHandler) ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error {
return ht.ErrNotImplemented
}
// CreateScript implements createScript operation.
//
// Create a new script.
@@ -107,7 +125,7 @@ func (UnimplementedHandler) DeleteScript(ctx context.Context, params DeleteScrip
//
// Delete the specified script policy by ID.
//
// DELETE /script-policy/{ScriptPolicyID}
// DELETE /script-policy/id/{ScriptPolicyID}
func (UnimplementedHandler) DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error {
return ht.ErrNotImplemented
}
@@ -125,11 +143,20 @@ func (UnimplementedHandler) GetScript(ctx context.Context, params GetScriptParam
//
// Get the specified script policy by ID.
//
// GET /script-policy/{ScriptPolicyID}
// GET /script-policy/id/{ScriptPolicyID}
func (UnimplementedHandler) GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (r *ScriptPolicy, _ error) {
return r, ht.ErrNotImplemented
}
// GetScriptPolicyFromHash implements getScriptPolicyFromHash operation.
//
// Get the policy for the given hash of script source code.
//
// GET /script-policy/hash/{FromScriptHash}
func (UnimplementedHandler) GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (r *ScriptPolicy, _ error) {
return r, ht.ErrNotImplemented
}
// GetSubmission implements getSubmission operation.
//
// Retrieve map with ID.
@@ -144,16 +171,7 @@ func (UnimplementedHandler) GetSubmission(ctx context.Context, params GetSubmiss
// 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) {
func (UnimplementedHandler) ListScriptPolicy(ctx context.Context, req *ListScriptPolicyReq) (r []ScriptPolicy, _ error) {
return r, ht.ErrNotImplemented
}
@@ -162,7 +180,7 @@ func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsP
// Get list of submissions.
//
// GET /submissions
func (UnimplementedHandler) ListSubmissions(ctx context.Context, params ListSubmissionsParams) (r []Submission, _ error) {
func (UnimplementedHandler) ListSubmissions(ctx context.Context, req *ListSubmissionsReq) (r []Submission, _ error) {
return r, ht.ErrNotImplemented
}
@@ -188,7 +206,7 @@ func (UnimplementedHandler) UpdateScript(ctx context.Context, req *ScriptUpdate,
//
// Update the specified script policy by ID.
//
// POST /script-policy/{ScriptPolicyID}
// POST /script-policy/id/{ScriptPolicyID}
func (UnimplementedHandler) UpdateScriptPolicy(ctx context.Context, req *ScriptPolicyUpdate, params UpdateScriptPolicyParams) error {
return ht.ErrNotImplemented
}

View File

@@ -8,31 +8,146 @@ import (
"github.com/ogen-go/ogen/validate"
)
func (s *Script) Validate() error {
func (s *ListScriptPolicyReq) 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")
if err := s.Page.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Name",
Name: "Page",
Error: err,
})
}
if err := func() error {
if value, ok := s.Filter.Get(); ok {
if err := func() error {
if err := value.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return err
}
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Filter",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *ListSubmissionsReq) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Page.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Page",
Error: err,
})
}
if err := func() error {
if value, ok := s.Filter.Get(); ok {
if err := func() error {
if err := value.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return err
}
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Filter",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *Pagination) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := (validate.Int{
MinSet: true,
Min: 1,
MaxSet: false,
Max: 0,
MinExclusive: false,
MaxExclusive: false,
MultipleOfSet: false,
MultipleOf: 0,
}).Validate(int64(s.Page)); err != nil {
return errors.Wrap(err, "int")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Page",
Error: err,
})
}
if err := func() error {
if err := (validate.Int{
MinSet: true,
Min: 1,
MaxSet: true,
Max: 100,
MinExclusive: false,
MaxExclusive: false,
MultipleOfSet: false,
MultipleOf: 0,
}).Validate(int64(s.Limit)); err != nil {
return errors.Wrap(err, "int")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Limit",
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: 16,
@@ -83,25 +198,6 @@ func (s *ScriptCreate) Validate() error {
}
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,
@@ -158,19 +254,19 @@ func (s *ScriptPolicy) Validate() error {
return nil
}
func (s *ScriptUpdate) Validate() error {
func (s *ScriptPolicyFilter) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if value, ok := s.Name.Get(); ok {
if value, ok := s.FromScriptHash.Get(); ok {
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 128,
MinLength: 16,
MinLengthSet: true,
MaxLength: 16,
MaxLengthSet: true,
Email: false,
Hostname: false,
@@ -186,10 +282,22 @@ func (s *ScriptUpdate) Validate() error {
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Name",
Name: "FromScriptHash",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *ScriptUpdate) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if value, ok := s.Source.Get(); ok {
if err := func() error {
@@ -321,3 +429,67 @@ func (s *SubmissionCreate) Validate() error {
}
return nil
}
func (s *SubmissionFilter) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if value, ok := s.DisplayName.Get(); ok {
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 128,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: nil,
}).Validate(string(value)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
return err
}
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "DisplayName",
Error: err,
})
}
if err := func() error {
if value, ok := s.Creator.Get(); ok {
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 128,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: nil,
}).Validate(string(value)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
return err
}
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "Creator",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}

View File

@@ -2,19 +2,16 @@ package cmds
import (
"fmt"
"net/http"
"git.itzana.me/strafesnet/go-grpc/auth"
"git.itzana.me/strafesnet/maps-service/pkg/api"
"git.itzana.me/strafesnet/maps-service/pkg/datastore/gormstore"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/service"
"git.itzana.me/strafesnet/maps-service/pkg/service_internal"
"github.com/nats-io/nats.go"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"net/http"
)
func NewServeCommand() *cli.Command {
@@ -65,12 +62,6 @@ func NewServeCommand() *cli.Command {
Value: 8080,
EnvVars: []string{"PORT"},
},
&cli.IntFlag{
Name: "port-internal",
Usage: "Port to listen on for internal api",
Value: 8081,
EnvVars: []string{"PORT_INTERNAL"},
},
&cli.StringFlag{
Name: "auth-rpc-host",
Usage: "Host of auth rpc",
@@ -128,37 +119,5 @@ func serve(ctx *cli.Context) error {
log.WithError(err).Fatal("failed to initialize api server")
}
svc2 := &service_internal.Service{
DB: db,
Nats: js,
}
srv2, err := internal.NewServer(svc2, internal.WithPathPrefix("/v1"))
if err != nil {
log.WithError(err).Fatal("failed to initialize api server")
}
// Channel to collect errors
errChan := make(chan error, 2)
// First server
go func(errChan chan error) {
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port-internal")), srv2)
}(errChan)
// Second server
go func(errChan chan error) {
errChan <- http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv)
}(errChan)
// Wait for the first error or completion of both tasks
for i := 0; i < 2; i++ {
err := <-errChan
if err != nil {
fmt.Println("Exiting due to:", err)
return err
}
}
log.Println("Both servers have stopped.")
return nil
return http.ListenAndServe(fmt.Sprintf(":%d", ctx.Int("port")), srv)
}

View File

@@ -33,7 +33,6 @@ type Scripts interface {
Create(ctx context.Context, smap model.Script) (model.Script, 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.Script, error)
}
type ScriptPolicy interface {

View File

@@ -19,18 +19,16 @@ func (env *ScriptPolicy) Get(ctx context.Context, id int64) (model.ScriptPolicy,
if errors.Is(err, gorm.ErrRecordNotFound) {
return mdl, datastore.ErrNotExist
}
return mdl, err
}
return mdl, nil
}
func (env *ScriptPolicy) GetFromHash(ctx context.Context, hash uint64) (model.ScriptPolicy, error) {
var mdl model.ScriptPolicy
if err := env.db.Take(&mdl,"from_script_hash = ?", hash).Error; err != nil {
if err := env.db.Model(&model.ScriptPolicy{}).Where("hash = ?", hash).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return mdl, datastore.ErrNotExist
}
return mdl, err
}
return mdl, nil
}

View File

@@ -19,7 +19,6 @@ func (env *Scripts) Get(ctx context.Context, id int64) (model.Script, error) {
if errors.Is(err, gorm.ErrRecordNotFound) {
return mdl, datastore.ErrNotExist
}
return mdl, err
}
return mdl, nil
}

View File

@@ -20,7 +20,6 @@ func (env *Submissions) Get(ctx context.Context, id int64) (model.Submission, er
if errors.Is(err, gorm.ErrRecordNotFound) {
return submission, datastore.ErrNotExist
}
return submission, err
}
return submission, nil
}

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,828 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"math/bits"
"strconv"
"github.com/go-faster/errors"
"github.com/go-faster/jx"
"github.com/ogen-go/ogen/validate"
)
// Encode implements json.Marshaler.
func (s *Error) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *Error) encodeFields(e *jx.Encoder) {
{
e.FieldStart("code")
e.Int64(s.Code)
}
{
e.FieldStart("message")
e.Str(s.Message)
}
}
var jsonFieldsNameOfError = [2]string{
0: "code",
1: "message",
}
// Decode decodes Error from json.
func (s *Error) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode Error to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "code":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Int64()
s.Code = int64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"code\"")
}
case "message":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Message = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"message\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode Error")
}
// 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(jsonFieldsNameOfError) {
name = jsonFieldsNameOfError[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 *Error) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *Error) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ID) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ID) encodeFields(e *jx.Encoder) {
{
e.FieldStart("ID")
e.Int64(s.ID)
}
}
var jsonFieldsNameOfID = [1]string{
0: "ID",
}
// Decode decodes ID from json.
func (s *ID) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ID 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\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ID")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfID) {
name = jsonFieldsNameOfID[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 *ID) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ID) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes int64 as json.
func (o OptInt64) Encode(e *jx.Encoder) {
if !o.Set {
return
}
e.Int64(int64(o.Value))
}
// Decode decodes int64 from json.
func (o *OptInt64) Decode(d *jx.Decoder) error {
if o == nil {
return errors.New("invalid: unable to decode OptInt64 to nil")
}
o.Set = true
v, err := d.Int64()
if err != nil {
return err
}
o.Value = int64(v)
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s OptInt64) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *OptInt64) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *Script) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *Script) encodeFields(e *jx.Encoder) {
{
e.FieldStart("ID")
e.Int64(s.ID)
}
{
e.FieldStart("Name")
e.Str(s.Name)
}
{
e.FieldStart("Hash")
e.Str(s.Hash)
}
{
e.FieldStart("Source")
e.Str(s.Source)
}
{
e.FieldStart("SubmissionID")
e.Int64(s.SubmissionID)
}
}
var jsonFieldsNameOfScript = [5]string{
0: "ID",
1: "Name",
2: "Hash",
3: "Source",
4: "SubmissionID",
}
// Decode decodes Script from json.
func (s *Script) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode Script 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 "Name":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Name = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Name\"")
}
case "Hash":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Str()
s.Hash = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Hash\"")
}
case "Source":
requiredBitSet[0] |= 1 << 3
if err := func() error {
v, err := d.Str()
s.Source = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Source\"")
}
case "SubmissionID":
requiredBitSet[0] |= 1 << 4
if err := func() error {
v, err := d.Int64()
s.SubmissionID = int64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"SubmissionID\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode Script")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00011111,
} {
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(jsonFieldsNameOfScript) {
name = jsonFieldsNameOfScript[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 *Script) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *Script) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ScriptCreate) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ScriptCreate) encodeFields(e *jx.Encoder) {
{
e.FieldStart("Name")
e.Str(s.Name)
}
{
e.FieldStart("Source")
e.Str(s.Source)
}
{
if s.SubmissionID.Set {
e.FieldStart("SubmissionID")
s.SubmissionID.Encode(e)
}
}
}
var jsonFieldsNameOfScriptCreate = [3]string{
0: "Name",
1: "Source",
2: "SubmissionID",
}
// Decode decodes ScriptCreate from json.
func (s *ScriptCreate) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ScriptCreate to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "Name":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Str()
s.Name = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Name\"")
}
case "Source":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Source = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Source\"")
}
case "SubmissionID":
if err := func() error {
s.SubmissionID.Reset()
if err := s.SubmissionID.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"SubmissionID\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ScriptCreate")
}
// 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(jsonFieldsNameOfScriptCreate) {
name = jsonFieldsNameOfScriptCreate[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 *ScriptCreate) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ScriptCreate) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ScriptPolicy) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ScriptPolicy) encodeFields(e *jx.Encoder) {
{
e.FieldStart("ID")
e.Int64(s.ID)
}
{
e.FieldStart("FromScriptHash")
e.Str(s.FromScriptHash)
}
{
e.FieldStart("ToScriptID")
e.Int64(s.ToScriptID)
}
{
e.FieldStart("Policy")
e.Int32(s.Policy)
}
}
var jsonFieldsNameOfScriptPolicy = [4]string{
0: "ID",
1: "FromScriptHash",
2: "ToScriptID",
3: "Policy",
}
// Decode decodes ScriptPolicy from json.
func (s *ScriptPolicy) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ScriptPolicy 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 "FromScriptHash":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.FromScriptHash = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"FromScriptHash\"")
}
case "ToScriptID":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Int64()
s.ToScriptID = int64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"ToScriptID\"")
}
case "Policy":
requiredBitSet[0] |= 1 << 3
if err := func() error {
v, err := d.Int32()
s.Policy = int32(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Policy\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ScriptPolicy")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00001111,
} {
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(jsonFieldsNameOfScriptPolicy) {
name = jsonFieldsNameOfScriptPolicy[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 *ScriptPolicy) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ScriptPolicy) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ScriptPolicyCreate) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ScriptPolicyCreate) encodeFields(e *jx.Encoder) {
{
e.FieldStart("FromScriptID")
e.Int64(s.FromScriptID)
}
{
e.FieldStart("ToScriptID")
e.Int64(s.ToScriptID)
}
{
e.FieldStart("Policy")
e.Int32(s.Policy)
}
}
var jsonFieldsNameOfScriptPolicyCreate = [3]string{
0: "FromScriptID",
1: "ToScriptID",
2: "Policy",
}
// Decode decodes ScriptPolicyCreate from json.
func (s *ScriptPolicyCreate) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ScriptPolicyCreate to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "FromScriptID":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Int64()
s.FromScriptID = int64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"FromScriptID\"")
}
case "ToScriptID":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Int64()
s.ToScriptID = int64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"ToScriptID\"")
}
case "Policy":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Int32()
s.Policy = int32(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"Policy\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ScriptPolicyCreate")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000111,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfScriptPolicyCreate) {
name = jsonFieldsNameOfScriptPolicyCreate[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 *ScriptPolicyCreate) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ScriptPolicyCreate) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}

View File

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

View File

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

View File

@@ -1,19 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
// OperationName is the ogen operation name
type OperationName = string
const (
ActionSubmissionAcceptedOperation OperationName = "ActionSubmissionAccepted"
ActionSubmissionReleasedOperation OperationName = "ActionSubmissionReleased"
ActionSubmissionUploadedOperation OperationName = "ActionSubmissionUploaded"
ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated"
CreateScriptOperation OperationName = "CreateScript"
CreateScriptPolicyOperation OperationName = "CreateScriptPolicy"
GetScriptOperation OperationName = "GetScript"
ListScriptPolicyOperation OperationName = "ListScriptPolicy"
ListScriptsOperation OperationName = "ListScripts"
UpdateSubmissionModelOperation OperationName = "UpdateSubmissionModel"
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,150 +0,0 @@
// 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) 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)
}
}

View File

@@ -1,40 +0,0 @@
// 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 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
}

View File

@@ -1,763 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"fmt"
"io"
"mime"
"net/http"
"github.com/go-faster/errors"
"github.com/go-faster/jx"
"github.com/ogen-go/ogen/ogenerrors"
"github.com/ogen-go/ogen/validate"
)
func decodeActionSubmissionAcceptedResponse(resp *http.Response) (res *ActionSubmissionAcceptedNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionAcceptedNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionReleasedResponse(resp *http.Response) (res *ActionSubmissionReleasedNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionReleasedNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionUploadedResponse(resp *http.Response) (res *ActionSubmissionUploadedNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionUploadedNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeActionSubmissionValidatedResponse(resp *http.Response) (res *ActionSubmissionValidatedNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &ActionSubmissionValidatedNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeCreateScriptResponse(resp *http.Response) (res *ID, _ error) {
switch resp.StatusCode {
case 201:
// Code 201.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response ID
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeCreateScriptPolicyResponse(resp *http.Response) (res *ID, _ error) {
switch resp.StatusCode {
case 201:
// Code 201.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response ID
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeGetScriptResponse(resp *http.Response) (res *Script, _ error) {
switch resp.StatusCode {
case 200:
// Code 200.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Script
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if err := response.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return &response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeListScriptPolicyResponse(resp *http.Response) (res []ScriptPolicy, _ error) {
switch resp.StatusCode {
case 200:
// Code 200.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response []ScriptPolicy
if err := func() error {
response = make([]ScriptPolicy, 0)
if err := d.Arr(func(d *jx.Decoder) error {
var elem ScriptPolicy
if err := elem.Decode(d); err != nil {
return err
}
response = append(response, elem)
return nil
}); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if response == nil {
return errors.New("nil is invalid value")
}
var failures []validate.FieldError
for i, elem := range response {
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
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeListScriptsResponse(resp *http.Response) (res []Script, _ error) {
switch resp.StatusCode {
case 200:
// Code 200.
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response []Script
if err := func() error {
response = make([]Script, 0)
if err := d.Arr(func(d *jx.Decoder) error {
var elem Script
if err := elem.Decode(d); err != nil {
return err
}
response = append(response, elem)
return nil
}); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
// Validate response.
if err := func() error {
if response == nil {
return errors.New("nil is invalid value")
}
var failures []validate.FieldError
for i, elem := range response {
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
}(); err != nil {
return res, errors.Wrap(err, "validate")
}
return response, nil
default:
return res, validate.InvalidContentType(ct)
}
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}
func decodeUpdateSubmissionModelResponse(resp *http.Response) (res *UpdateSubmissionModelNoContent, _ error) {
switch resp.StatusCode {
case 204:
// Code 204.
return &UpdateSubmissionModelNoContent{}, nil
}
// Convenient error response.
defRes, err := func() (res *ErrorStatusCode, err error) {
ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type"))
if err != nil {
return res, errors.Wrap(err, "parse media type")
}
switch {
case ct == "application/json":
buf, err := io.ReadAll(resp.Body)
if err != nil {
return res, err
}
d := jx.DecodeBytes(buf)
var response Error
if err := func() error {
if err := response.Decode(d); err != nil {
return err
}
if err := d.Skip(); err != io.EOF {
return errors.New("unexpected trailing data")
}
return nil
}(); err != nil {
err = &ogenerrors.DecodeBodyError{
ContentType: ct,
Body: buf,
Err: err,
}
return res, err
}
return &ErrorStatusCode{
StatusCode: resp.StatusCode,
Response: response,
}, nil
default:
return res, validate.InvalidContentType(ct)
}
}()
if err != nil {
return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode)
}
return res, errors.Wrap(defRes, "error")
}

View File

@@ -1,154 +0,0 @@
// 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 encodeActionSubmissionAcceptedResponse(response *ActionSubmissionAcceptedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionReleasedResponse(response *ActionSubmissionReleasedNoContent, w http.ResponseWriter, span trace.Span) error {
w.WriteHeader(204)
span.SetStatus(codes.Ok, http.StatusText(204))
return nil
}
func encodeActionSubmissionUploadedResponse(response *ActionSubmissionUploadedNoContent, w http.ResponseWriter, span trace.Span) error {
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 encodeCreateScriptResponse(response *ID, 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 *ID, 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 encodeUpdateSubmissionModelResponse(response *UpdateSubmissionModelNoContent, 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
}

View File

@@ -1,745 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"net/http"
"net/url"
"strings"
"github.com/ogen-go/ogen/uri"
)
func (s *Server) cutPrefix(path string) (string, bool) {
prefix := s.cfg.Prefix
if prefix == "" {
return path, true
}
if !strings.HasPrefix(path, prefix) {
// Prefix doesn't match.
return "", false
}
// Cut prefix from the path.
return strings.TrimPrefix(path, prefix), true
}
// ServeHTTP serves http request as defined by OpenAPI v3 specification,
// calling handler that matches the path or returning not found error.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
elem := r.URL.Path
elemIsEscaped := false
if rawPath := r.URL.RawPath; rawPath != "" {
if normalized, ok := uri.NormalizeEscapedPath(rawPath); ok {
elem = normalized
elemIsEscaped = strings.ContainsRune(elem, '%')
}
}
elem, ok := s.cutPrefix(elem)
if !ok || len(elem) == 0 {
s.notFound(w, r)
return
}
args := [1]string{}
// Static code generated router with unwrapped path search.
switch {
default:
if len(elem) == 0 {
break
}
switch elem[0] {
case '/': // Prefix: "/s"
origElem := elem
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'c': // Prefix: "cript"
origElem := elem
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case '-': // Prefix: "-policy"
origElem := elem
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "GET":
s.handleListScriptPolicyRequest([0]string{}, elemIsEscaped, w, r)
case "POST":
s.handleCreateScriptPolicyRequest([0]string{}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "GET,POST")
}
return
}
elem = origElem
case 's': // Prefix: "s"
origElem := elem
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
switch r.Method {
case "GET":
s.handleListScriptsRequest([0]string{}, elemIsEscaped, w, r)
case "POST":
s.handleCreateScriptRequest([0]string{}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "GET,POST")
}
return
}
switch elem[0] {
case '/': // Prefix: "/"
origElem := elem
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
elem = elem[l:]
} else {
break
}
// Param: "ScriptID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "GET":
s.handleGetScriptRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "GET")
}
return
}
elem = origElem
}
elem = origElem
}
elem = origElem
case 'u': // Prefix: "ubmissions/"
origElem := elem
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
elem = elem[l:]
} else {
break
}
// Param: "SubmissionID"
// Match until "/"
idx := strings.IndexByte(elem, '/')
if idx < 0 {
idx = len(elem)
}
args[0] = elem[:idx]
elem = elem[idx:]
if len(elem) == 0 {
break
}
switch elem[0] {
case '/': // Prefix: "/"
origElem := elem
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'm': // Prefix: "model"
origElem := elem
if l := len("model"); len(elem) >= l && elem[0:l] == "model" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleUpdateSubmissionModelRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
case 's': // Prefix: "status/"
origElem := elem
if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'r': // Prefix: "releaser-released"
origElem := elem
if l := len("releaser-released"); len(elem) >= l && elem[0:l] == "releaser-released" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionReleasedRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
case 'v': // Prefix: "validator-"
origElem := elem
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'f': // Prefix: "failed"
origElem := elem
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionAcceptedRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
case 'u': // Prefix: "uploaded"
origElem := elem
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionUploadedRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
case 'v': // Prefix: "validated"
origElem := elem
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch r.Method {
case "POST":
s.handleActionSubmissionValidatedRequest([1]string{
args[0],
}, elemIsEscaped, w, r)
default:
s.notAllowed(w, r, "POST")
}
return
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
}
s.notFound(w, r)
}
// Route is route object.
type Route struct {
name string
summary string
operationID string
pathPattern string
count int
args [1]string
}
// Name returns ogen operation name.
//
// It is guaranteed to be unique and not empty.
func (r Route) Name() string {
return r.name
}
// Summary returns OpenAPI summary.
func (r Route) Summary() string {
return r.summary
}
// OperationID returns OpenAPI operationId.
func (r Route) OperationID() string {
return r.operationID
}
// PathPattern returns OpenAPI path.
func (r Route) PathPattern() string {
return r.pathPattern
}
// Args returns parsed arguments.
func (r Route) Args() []string {
return r.args[:r.count]
}
// FindRoute finds Route for given method and path.
//
// Note: this method does not unescape path or handle reserved characters in path properly. Use FindPath instead.
func (s *Server) FindRoute(method, path string) (Route, bool) {
return s.FindPath(method, &url.URL{Path: path})
}
// FindPath finds Route for given method and URL.
func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) {
var (
elem = u.Path
args = r.args
)
if rawPath := u.RawPath; rawPath != "" {
if normalized, ok := uri.NormalizeEscapedPath(rawPath); ok {
elem = normalized
}
defer func() {
for i, arg := range r.args[:r.count] {
if unescaped, err := url.PathUnescape(arg); err == nil {
r.args[i] = unescaped
}
}
}()
}
elem, ok := s.cutPrefix(elem)
if !ok {
return r, false
}
// Static code generated router with unwrapped path search.
switch {
default:
if len(elem) == 0 {
break
}
switch elem[0] {
case '/': // Prefix: "/s"
origElem := elem
if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'c': // Prefix: "cript"
origElem := elem
if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case '-': // Prefix: "-policy"
origElem := elem
if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "GET":
r.name = ListScriptPolicyOperation
r.summary = "Get list of script policies"
r.operationID = "listScriptPolicy"
r.pathPattern = "/script-policy"
r.args = args
r.count = 0
return r, true
case "POST":
r.name = CreateScriptPolicyOperation
r.summary = "Create a new script policy"
r.operationID = "createScriptPolicy"
r.pathPattern = "/script-policy"
r.args = args
r.count = 0
return r, true
default:
return
}
}
elem = origElem
case 's': // Prefix: "s"
origElem := elem
if l := len("s"); len(elem) >= l && elem[0:l] == "s" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
switch method {
case "GET":
r.name = ListScriptsOperation
r.summary = "Get list of scripts"
r.operationID = "listScripts"
r.pathPattern = "/scripts"
r.args = args
r.count = 0
return r, true
case "POST":
r.name = CreateScriptOperation
r.summary = "Create a new script"
r.operationID = "createScript"
r.pathPattern = "/scripts"
r.args = args
r.count = 0
return r, true
default:
return
}
}
switch elem[0] {
case '/': // Prefix: "/"
origElem := elem
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
elem = elem[l:]
} else {
break
}
// Param: "ScriptID"
// Leaf parameter
args[0] = elem
elem = ""
if len(elem) == 0 {
// Leaf node.
switch method {
case "GET":
r.name = GetScriptOperation
r.summary = "Get the specified script by ID"
r.operationID = "getScript"
r.pathPattern = "/scripts/{ScriptID}"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
}
elem = origElem
}
elem = origElem
case 'u': // Prefix: "ubmissions/"
origElem := elem
if l := len("ubmissions/"); len(elem) >= l && elem[0:l] == "ubmissions/" {
elem = elem[l:]
} else {
break
}
// Param: "SubmissionID"
// Match until "/"
idx := strings.IndexByte(elem, '/')
if idx < 0 {
idx = len(elem)
}
args[0] = elem[:idx]
elem = elem[idx:]
if len(elem) == 0 {
break
}
switch elem[0] {
case '/': // Prefix: "/"
origElem := elem
if l := len("/"); len(elem) >= l && elem[0:l] == "/" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'm': // Prefix: "model"
origElem := elem
if l := len("model"); len(elem) >= l && elem[0:l] == "model" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = UpdateSubmissionModelOperation
r.summary = "Update model following role restrictions"
r.operationID = "updateSubmissionModel"
r.pathPattern = "/submissions/{SubmissionID}/model"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 's': // Prefix: "status/"
origElem := elem
if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'r': // Prefix: "releaser-released"
origElem := elem
if l := len("releaser-released"); len(elem) >= l && elem[0:l] == "releaser-released" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionReleasedOperation
r.summary = "(Internal endpoint) Role Releaser changes status from releasing -> released"
r.operationID = "actionSubmissionReleased"
r.pathPattern = "/submissions/{SubmissionID}/status/releaser-released"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 'v': // Prefix: "validator-"
origElem := elem
if l := len("validator-"); len(elem) >= l && elem[0:l] == "validator-" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
break
}
switch elem[0] {
case 'f': // Prefix: "failed"
origElem := elem
if l := len("failed"); len(elem) >= l && elem[0:l] == "failed" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionAcceptedOperation
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Accepted"
r.operationID = "actionSubmissionAccepted"
r.pathPattern = "/submissions/{SubmissionID}/status/validator-failed"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 'u': // Prefix: "uploaded"
origElem := elem
if l := len("uploaded"); len(elem) >= l && elem[0:l] == "uploaded" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionUploadedOperation
r.summary = "(Internal endpoint) Role Validator changes status from Uploading -> Uploaded"
r.operationID = "actionSubmissionUploaded"
r.pathPattern = "/submissions/{SubmissionID}/status/validator-uploaded"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
case 'v': // Prefix: "validated"
origElem := elem
if l := len("validated"); len(elem) >= l && elem[0:l] == "validated" {
elem = elem[l:]
} else {
break
}
if len(elem) == 0 {
// Leaf node.
switch method {
case "POST":
r.name = ActionSubmissionValidatedOperation
r.summary = "(Internal endpoint) Role Validator changes status from Validating -> Validated"
r.operationID = "actionSubmissionValidated"
r.pathPattern = "/submissions/{SubmissionID}/status/validator-validated"
r.args = args
r.count = 1
return r, true
default:
return
}
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
elem = origElem
}
}
return r, false
}

View File

@@ -1,413 +0,0 @@
// 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)
}
// ActionSubmissionAcceptedNoContent is response for ActionSubmissionAccepted operation.
type ActionSubmissionAcceptedNoContent struct{}
// ActionSubmissionReleasedNoContent is response for ActionSubmissionReleased operation.
type ActionSubmissionReleasedNoContent 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/Id
type ID struct {
ID int64 `json:"ID"`
}
// GetID returns the value of ID.
func (s *ID) GetID() int64 {
return s.ID
}
// SetID sets the value of ID.
func (s *ID) SetID(val int64) {
s.ID = 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"`
SubmissionID int64 `json:"SubmissionID"`
}
// 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
}
// GetSubmissionID returns the value of SubmissionID.
func (s *Script) GetSubmissionID() int64 {
return s.SubmissionID
}
// 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
}
// SetSubmissionID sets the value of SubmissionID.
func (s *Script) SetSubmissionID(val int64) {
s.SubmissionID = val
}
// Ref: #/components/schemas/ScriptCreate
type ScriptCreate struct {
Name string `json:"Name"`
Source string `json:"Source"`
SubmissionID OptInt64 `json:"SubmissionID"`
}
// 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
}
// GetSubmissionID returns the value of SubmissionID.
func (s *ScriptCreate) GetSubmissionID() OptInt64 {
return s.SubmissionID
}
// 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
}
// SetSubmissionID sets the value of SubmissionID.
func (s *ScriptCreate) SetSubmissionID(val OptInt64) {
s.SubmissionID = 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
}
// UpdateSubmissionModelNoContent is response for UpdateSubmissionModel operation.
type UpdateSubmissionModelNoContent struct{}

View File

@@ -1,94 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"context"
)
// Handler handles operations described by OpenAPI v3 specification.
type Handler interface {
// 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
// ActionSubmissionReleased implements actionSubmissionReleased operation.
//
// (Internal endpoint) Role Releaser changes status from releasing -> released.
//
// POST /submissions/{SubmissionID}/status/releaser-released
ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
//
// (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
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
CreateScript(ctx context.Context, req *ScriptCreate) (*ID, error)
// CreateScriptPolicy implements createScriptPolicy operation.
//
// Create a new script policy.
//
// POST /script-policy
CreateScriptPolicy(ctx context.Context, req *ScriptPolicyCreate) (*ID, 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)
// UpdateSubmissionModel implements updateSubmissionModel operation.
//
// Update model following role restrictions.
//
// POST /submissions/{SubmissionID}/model
UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) error
// NewError creates *ErrorStatusCode from error returned by handler.
//
// Used for common default response.
NewError(ctx context.Context, err error) *ErrorStatusCode
}
// Server implements http server based on OpenAPI v3 specification and
// calls Handler to handle requests.
type Server struct {
h Handler
baseServer
}
// NewServer creates new Server.
func NewServer(h Handler, opts ...ServerOption) (*Server, error) {
s, err := newServerConfig(opts...).baseServer()
if err != nil {
return nil, err
}
return &Server{
h: h,
baseServer: s,
}, nil
}

View File

@@ -1,112 +0,0 @@
// 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{}
// 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
}
// ActionSubmissionReleased implements actionSubmissionReleased operation.
//
// (Internal endpoint) Role Releaser changes status from releasing -> released.
//
// POST /submissions/{SubmissionID}/status/releaser-released
func (UnimplementedHandler) ActionSubmissionReleased(ctx context.Context, params ActionSubmissionReleasedParams) error {
return ht.ErrNotImplemented
}
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
//
// (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
}
// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
func (UnimplementedHandler) CreateScript(ctx context.Context, req *ScriptCreate) (r *ID, _ 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 *ID, _ 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
}
// UpdateSubmissionModel implements updateSubmissionModel operation.
//
// Update model following role restrictions.
//
// POST /submissions/{SubmissionID}/model
func (UnimplementedHandler) UpdateSubmissionModel(ctx context.Context, params UpdateSubmissionModelParams) 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
}

View File

@@ -1,159 +0,0 @@
// Code generated by ogen, DO NOT EDIT.
package api
import (
"github.com/go-faster/errors"
"github.com/ogen-go/ogen/validate"
)
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
}

View File

@@ -8,22 +8,25 @@ package model
type ValidateRequest struct {
// submission_id is passed back in the response message
SubmissionID int64
ModelID int64
ModelVersion int64
ValidatedModelID int64 // optional value
ModelID uint64
ModelVersion uint64
ValidatedModelID uint64 // optional value
}
// Create a new map
type PublishNewRequest struct {
SubmissionID int64
ModelID int64
ModelVersion int64
ModelName string
ModelID uint64
ModelVersion uint64
Creator string
DisplayName string
GameID uint32
//games HashSet<GameID>
}
type PublishFixRequest struct {
SubmissionID int64
ModelID int64
ModelVersion int64
TargetAssetID int64
ModelID uint64
ModelVersion uint64
TargetAssetID uint64
}

View File

@@ -17,7 +17,7 @@ type ScriptPolicy struct {
// Hash of the source code that leads to this policy.
// If this is a replacement mapping, the original source may not be pointed to by any policy.
// The original source should still exist in the scripts table, which can be located by the same hash.
FromScriptHash int64 // postgres does not support unsigned integers, so we have to pretend
FromScriptHash uint64
// The ID of the replacement source (ScriptPolicyReplace)
// or verbatim source (ScriptPolicyAllowed)
// or 0 (other)

View File

@@ -1,32 +1,10 @@
package model
import (
"fmt"
"strconv"
"time"
"github.com/dchest/siphash"
)
// compute the hash of a source code string
func HashSource(source string) uint64{
return siphash.Hash(0, 0, []byte(source))
}
// format a hash value as a hexidecimal string
func HashFormat(hash uint64) string{
return fmt.Sprintf("%016x", hash)
}
// parse a hexidecimal hash string
func HashParse(hash string) (uint64, error){
return strconv.ParseUint(hash, 16, 64)
}
import "time"
type Script struct {
ID int64 `gorm:"primaryKey"`
Name string
Hash int64 // postgres does not support unsigned integers, so we have to pretend
Hash uint64
Source string
SubmissionID int64 // which submission did this script first appear in
CreatedAt time.Time

View File

@@ -5,18 +5,14 @@ import "time"
type Status int32
const (
// Phase: Final Status
StatusReleased Status = 9
StatusRejected Status = 8
StatusPublished Status = 8
StatusRejected Status = 7
// Phase: Testing
StatusUploaded Status = 7 // uploaded to the group, but pending release
StatusUploading Status = 6
StatusPublishing Status = 6
StatusValidated Status = 5
StatusValidating Status = 4
StatusAccepted Status = 3 // pending script review, can re-trigger validation
StatusAccepted Status = 3
// Phase: Creation
StatusChangesRequested Status = 2
StatusSubmitted Status = 1
StatusUnderConstruction Status = 0
@@ -29,10 +25,10 @@ type Submission struct {
GameID int32
CreatedAt time.Time
UpdatedAt time.Time
Submitter int64 // UserID
AssetID int64
AssetVersion int64
Submitter uint64 // UserID
AssetID uint64
AssetVersion uint64
Completed bool // Has this version of the map been completed at least once on maptest
TargetAssetID int64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
TargetAssetID uint64 // where to upload map fix. if the TargetAssetID is 0, it's a new map.
StatusID Status
}

View File

@@ -2,6 +2,8 @@ package service
import (
"context"
"fmt"
"strconv"
"git.itzana.me/strafesnet/maps-service/pkg/api"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
@@ -51,26 +53,18 @@ func (svc *Service) CreateScriptPolicy(ctx context.Context, req *api.ScriptPolic
// Get list of script policies.
//
// GET /script-policy
func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptPolicyParams) ([]api.ScriptPolicy, error) {
func (svc *Service) ListScriptPolicy(ctx context.Context, request *api.ListScriptPolicyReq) ([]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)
//fmt.Println(request)
if request.Filter.IsSet() {
filter.AddNotNil("from_script_hash", request.Filter.Value.FromScriptHash)
filter.AddNotNil("to_script_id", request.Filter.Value.ToScriptID)
filter.AddNotNil("policy", request.Filter.Value.Policy)
}
items, err := svc.DB.ScriptPolicy().List(ctx, filter, model.Page{
Number: params.Page,
Size: params.Limit,
Number: request.Page.GetPage(),
Size: request.Page.GetLimit(),
})
if err != nil {
return nil, err
@@ -80,7 +74,7 @@ func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptP
for i := 0; i < len(items); i++ {
resp = append(resp, api.ScriptPolicy{
ID: items[i].ID,
FromScriptHash: model.HashFormat(uint64(items[i].FromScriptHash)),
FromScriptHash: fmt.Sprintf("%x", items[i].FromScriptHash),
ToScriptID: items[i].ToScriptID,
Policy: int32(items[i].Policy),
})
@@ -93,7 +87,7 @@ func (svc *Service) ListScriptPolicy(ctx context.Context, params api.ListScriptP
//
// Delete the specified script policy by ID.
//
// DELETE /script-policy/{ScriptPolicyID}
// DELETE /script-policy/id/{ScriptPolicyID}
func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScriptPolicyParams) error {
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
if !ok {
@@ -111,7 +105,7 @@ func (svc *Service) DeleteScriptPolicy(ctx context.Context, params api.DeleteScr
//
// Get the specified script policy by ID.
//
// GET /script-policy/{ScriptPolicyID}
// GET /script-policy/id/{ScriptPolicyID}
func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPolicyParams) (*api.ScriptPolicy, error) {
_, ok := ctx.Value("UserInfo").(UserInfo)
if !ok {
@@ -127,7 +121,39 @@ func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPol
return &api.ScriptPolicy{
ID: policy.ID,
FromScriptHash: model.HashFormat(uint64(policy.FromScriptHash)),
FromScriptHash: fmt.Sprintf("%x", policy.FromScriptHash),
ToScriptID: policy.ToScriptID,
Policy: int32(policy.Policy),
}, nil
}
// GetScriptPolicyFromHash implements getScriptPolicyFromHash operation.
//
// Get the policy for the given hash of script source code.
//
// GET /script-policy/hash/{FromScriptHash}
func (svc *Service) GetScriptPolicyFromHash(ctx context.Context, params api.GetScriptPolicyFromHashParams) (*api.ScriptPolicy, error) {
_, ok := ctx.Value("UserInfo").(UserInfo)
if !ok {
return nil, ErrUserInfo
}
// Read permission for script policy only requires you to be logged in
// parse hash from hex
hash, err := strconv.ParseUint(params.FromScriptHash, 16, 64)
if err != nil {
return nil, err
}
policy, err := svc.DB.ScriptPolicy().GetFromHash(ctx, hash)
if err != nil {
return nil, err
}
return &api.ScriptPolicy{
ID: policy.ID,
FromScriptHash: fmt.Sprintf("%x", policy.FromScriptHash),
ToScriptID: policy.ToScriptID,
Policy: int32(policy.Policy),
}, nil
@@ -137,7 +163,7 @@ func (svc *Service) GetScriptPolicy(ctx context.Context, params api.GetScriptPol
//
// Update the specified script policy by ID.
//
// POST /script-policy/{ScriptPolicyID}
// PATCH /script-policy/id/{ScriptPolicyID}
func (svc *Service) UpdateScriptPolicy(ctx context.Context, req *api.ScriptPolicyUpdate, params api.UpdateScriptPolicyParams) error {
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
if !ok {

View File

@@ -2,10 +2,12 @@ package service
import (
"context"
"fmt"
"git.itzana.me/strafesnet/maps-service/pkg/api"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
"git.itzana.me/strafesnet/maps-service/pkg/model"
"github.com/dchest/siphash"
)
// CreateScript implements createScript operation.
@@ -25,8 +27,7 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a
script, err := svc.DB.Scripts().Create(ctx, model.Script{
ID: 0,
Name: req.Name,
Hash: int64(model.HashSource(req.Source)),
Hash: siphash.Hash(0, 0, []byte(req.Source)),
Source: req.Source,
SubmissionID: req.SubmissionID.Or(0),
})
@@ -39,52 +40,6 @@ func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*a
}, 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.SubmissionID.IsSet(){
filter.AddNotNil("submission_id", params.SubmissionID.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 i := 0; i < len(items); i++ {
resp = append(resp, api.Script{
ID: items[i].ID,
Hash: model.HashFormat(uint64(items[i].Hash)),
Source: items[i].Source,
SubmissionID: items[i].SubmissionID,
})
}
return resp, nil
}
// DeleteScript implements deleteScript operation.
//
// Delete the specified script by ID.
@@ -123,8 +78,7 @@ func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (
return &api.Script{
ID: script.ID,
Name: script.Name,
Hash: model.HashFormat(uint64(script.Hash)),
Hash: fmt.Sprintf("%x", script.Hash),
Source: script.Source,
SubmissionID: script.SubmissionID,
}, nil
@@ -146,12 +100,9 @@ func (svc *Service) UpdateScript(ctx context.Context, req *api.ScriptUpdate, par
}
pmap := datastore.Optional()
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!
pmap.Add("hash", siphash.Hash(0, 0, []byte(source)))
}
if SubmissionID, ok := req.SubmissionID.Get(); ok {
pmap.Add("submission_id", SubmissionID)

View File

@@ -15,8 +15,6 @@ var (
)
var (
// has ScriptWrite
RoleQuat int32 = 255
// has SubmissionPublish
RoleMapAdmin int32 = 128
// has SubmissionReview
@@ -25,14 +23,12 @@ var (
type Roles struct {
// human roles
SubmissionRelease bool
SubmissionPublish bool
SubmissionReview bool
ScriptWrite bool
// Thumbnail bool
// MapDownload
// automated roles
Maptest bool
Validator bool
}
type UserInfo struct {
@@ -82,11 +78,8 @@ func (svc SecurityHandler) HandleCookieAuth(ctx context.Context, operationName a
// fix this when roblox udpates group roles
for _, r := range role.Roles {
if RoleQuat <= r.Rank {
roles.ScriptWrite = true
}
if RoleMapAdmin <= r.Rank {
roles.SubmissionRelease = true
roles.SubmissionPublish = true
}
if RoleMapCouncil <= r.Rank {
roles.SubmissionReview = true

View File

@@ -25,9 +25,6 @@ type Service struct {
// 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
}

View File

@@ -3,38 +3,12 @@ package service
import (
"context"
"encoding/json"
"errors"
"git.itzana.me/strafesnet/maps-service/pkg/api"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
"git.itzana.me/strafesnet/maps-service/pkg/model"
)
var(
CreationPhaseSubmissionsLimit = 20
CreationPhaseSubmissionStatuses = []model.Status{
model.StatusChangesRequested,
model.StatusSubmitted,
model.StatusUnderConstruction,
}
ActiveSubmissionStatuses = []model.Status{
model.StatusUploaded,
model.StatusUploading,
model.StatusValidated,
model.StatusValidating,
model.StatusAccepted,
model.StatusChangesRequested,
model.StatusSubmitted,
model.StatusUnderConstruction,
}
)
var (
ErrCreationPhaseSubmissionsLimit = errors.New("Active submissions limited to 20")
ErrActiveSubmissionSameAssetID = errors.New("There is an active submission with the same AssetID")
ErrActiveSubmissionSameTargetAssetID = errors.New("There is an active submission with the same TargetAssetID")
)
// POST /submissions
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionCreate) (*api.ID, error) {
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
@@ -42,71 +16,16 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
return nil, ErrUserInfo
}
userId := userInfo.UserID
// 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),
})
if err != nil {
return nil, err
}
if CreationPhaseSubmissionsLimit <= len(creation_submissions) {
return nil, ErrCreationPhaseSubmissionsLimit
}
}
// 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,
})
if err != nil {
return nil, err
}
if len(active_submissions) != 0{
return nil, ErrActiveSubmissionSameAssetID
}
}
// Check if an active submission with the same target asset id exists
if request.TargetAssetID.IsSet() && request.TargetAssetID.Value != 0{
filter := datastore.Optional()
filter.Add("target_asset_id", request.TargetAssetID.Value)
filter.Add("status_id", ActiveSubmissionStatuses)
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1,
Size: 1,
})
if err != nil {
return nil, err
}
if len(active_submissions) != 0{
return nil, ErrActiveSubmissionSameTargetAssetID
}
}
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
ID: 0,
DisplayName: request.DisplayName,
Creator: request.Creator,
GameID: request.GameID,
Submitter: int64(userId),
AssetID: request.AssetID,
AssetVersion: request.AssetVersion,
Submitter: userInfo.UserID,
AssetID: uint64(request.AssetID),
AssetVersion: uint64(request.AssetVersion),
Completed: false,
TargetAssetID: request.TargetAssetID.Value,
TargetAssetID: uint64(request.TargetAssetID.Value),
StatusID: model.StatusUnderConstruction,
})
if err != nil {
@@ -148,22 +67,18 @@ func (svc *Service) GetSubmission(ctx context.Context, params api.GetSubmissionP
// Get list of submissions.
//
// GET /submissions
func (svc *Service) ListSubmissions(ctx context.Context, params api.ListSubmissionsParams) ([]api.Submission, error) {
func (svc *Service) ListSubmissions(ctx context.Context, request *api.ListSubmissionsReq) ([]api.Submission, error) {
filter := datastore.Optional()
if params.DisplayName.IsSet(){
filter.Add("display_name", params.DisplayName.Value)
}
if params.Creator.IsSet(){
filter.Add("creator", params.Creator.Value)
}
if params.GameID.IsSet(){
filter.Add("game_id", params.GameID.Value)
//fmt.Println(request)
if request.Filter.IsSet() {
filter.AddNotNil("display_name", request.Filter.Value.DisplayName)
filter.AddNotNil("creator", request.Filter.Value.Creator)
filter.AddNotNil("game_id", request.Filter.Value.GameID)
}
items, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: params.Page,
Size: params.Limit,
Number: request.Page.GetPage(),
Size: request.Page.GetLimit(),
})
if err != nil {
return nil, err
@@ -212,7 +127,7 @@ func (svc *Service) SetSubmissionCompleted(ctx context.Context, params api.SetSu
return err
}
// UpdateSubmissionModel implements patchSubmissionModel operation.
// PatchSubmissionModel implements patchSubmissionModel operation.
//
// Update model following role restrictions.
//
@@ -230,7 +145,7 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
}
// check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) {
if !userInfo.IsSubmitter(submission.Submitter) {
return ErrPermissionDenied
}
@@ -243,6 +158,20 @@ func (svc *Service) UpdateSubmissionModel(ctx context.Context, params api.Update
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusChangesRequested, model.StatusSubmitted, model.StatusUnderConstruction}, pmap)
}
// ActionSubmissionPublish invokes actionSubmissionPublish operation.
//
// Role Validator changes status from Publishing -> Published.
//
// POST /submissions/{SubmissionID}/status/publish
func (svc *Service) ActionSubmissionPublish(ctx context.Context, params api.ActionSubmissionPublishParams) error {
println("[ActionSubmissionPublish] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusPublished)
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusPublishing}, smap)
}
// ActionSubmissionReject invokes actionSubmissionReject operation.
//
// Role Reviewer changes status from Submitted -> Rejected.
@@ -305,7 +234,7 @@ func (svc *Service) ActionSubmissionRevoke(ctx context.Context, params api.Actio
}
// check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) {
if !userInfo.IsSubmitter(submission.Submitter) {
return ErrPermissionDenied
}
@@ -333,7 +262,7 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
}
// check if caller is the submitter
if !userInfo.IsSubmitter(uint64(submission.Submitter)) {
if !userInfo.IsSubmitter(submission.Submitter) {
return ErrPermissionDenied
}
@@ -343,25 +272,25 @@ func (svc *Service) ActionSubmissionSubmit(ctx context.Context, params api.Actio
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUnderConstruction, model.StatusChangesRequested}, smap)
}
// ActionSubmissionTriggerUpload invokes actionSubmissionTriggerUpload operation.
// ActionSubmissionTriggerPublish invokes actionSubmissionTriggerPublish operation.
//
// Role Admin changes status from Validated -> Uploading.
// Role Admin changes status from Validated -> Publishing.
//
// POST /submissions/{SubmissionID}/status/trigger-upload
func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params api.ActionSubmissionTriggerUploadParams) error {
// POST /submissions/{SubmissionID}/status/trigger-publish
func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params api.ActionSubmissionTriggerPublishParams) error {
userInfo, ok := ctx.Value("UserInfo").(UserInfo)
if !ok {
return ErrUserInfo
}
// check if caller has required role
if !userInfo.Roles.SubmissionRelease {
if !userInfo.Roles.SubmissionPublish {
return ErrPermissionDenied
}
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusUploading)
smap.Add("status_id", model.StatusPublishing)
submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap)
if err != nil {
return err
@@ -374,8 +303,9 @@ func (svc *Service) ActionSubmissionTriggerUpload(ctx context.Context, params ap
SubmissionID: submission.ID,
ModelID: submission.AssetID,
ModelVersion: submission.AssetVersion,
// publish as displayname, whatever
ModelName: submission.DisplayName,
Creator: submission.Creator,
DisplayName: submission.DisplayName,
GameID: uint32(submission.GameID),
}
j, err := json.Marshal(publish_new_request)
@@ -444,3 +374,17 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params
return nil
}
// ActionSubmissionValidate invokes actionSubmissionValidate operation.
//
// Role Validator changes status from Validating -> Validated.
//
// POST /submissions/{SubmissionID}/status/validate
func (svc *Service) ActionSubmissionValidate(ctx context.Context, params api.ActionSubmissionValidateParams) error {
println("[ActionSubmissionValidate] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusValidated)
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
}

View File

@@ -1,80 +0,0 @@
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.ID, 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.ID{
ID: 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 i := 0; i < len(items); i++ {
resp = append(resp, api.ScriptPolicy{
ID: items[i].ID,
FromScriptHash: model.HashFormat(uint64(items[i].FromScriptHash)),
ToScriptID: items[i].ToScriptID,
Policy: int32(items[i].Policy),
})
}
return resp, nil
}

View File

@@ -1,97 +0,0 @@
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.ID, error) {
script, err := svc.DB.Scripts().Create(ctx, model.Script{
ID: 0,
Name: req.Name,
Hash: int64(model.HashSource(req.Source)),
Source: req.Source,
SubmissionID: req.SubmissionID.Or(0),
})
if err != nil {
return nil, err
}
return &api.ID{
ID: 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.SubmissionID.IsSet(){
filter.AddNotNil("submission_id", params.SubmissionID.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 i := 0; i < len(items); i++ {
resp = append(resp, api.Script{
ID: items[i].ID,
Hash: model.HashFormat(uint64(items[i].Hash)),
Source: items[i].Source,
SubmissionID: items[i].SubmissionID,
})
}
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,
SubmissionID: script.SubmissionID,
}, nil
}

View File

@@ -1,30 +0,0 @@
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(),
},
}
}

View File

@@ -1,83 +0,0 @@
package service_internal
import (
"context"
internal "git.itzana.me/strafesnet/maps-service/pkg/internal"
"git.itzana.me/strafesnet/maps-service/pkg/datastore"
"git.itzana.me/strafesnet/maps-service/pkg/model"
)
// UpdateSubmissionModel implements patchSubmissionModel operation.
//
// Update model following role restrictions.
//
// POST /submissions/{SubmissionID}/model
func (svc *Service) UpdateSubmissionModel(ctx context.Context, params internal.UpdateSubmissionModelParams) error {
// 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.Status{model.StatusValidating}, 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 {
println("[ActionSubmissionValidated] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusValidated)
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, 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 {
println("[ActionSubmissionAccepted] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusAccepted)
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidating}, smap)
}
// ActionSubmissionReleased implements actionSubmissionReleased operation.
//
// (Internal endpoint) Role Releaser changes status from Uploaded -> Released.
//
// POST /submissions/{SubmissionID}/status/releaser-released
func (svc *Service) ActionSubmissionReleased(ctx context.Context, params internal.ActionSubmissionReleasedParams) error {
println("[ActionSubmissionReleased] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusReleased)
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploaded}, smap)
}
// ActionSubmissionUploaded implements actionSubmissionUploaded operation.
//
// (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 {
println("[ActionSubmissionUploaded] Implicit Validator permission granted!")
// transaction
smap := datastore.Optional()
smap.Add("status_id", model.StatusUploaded)
if params.TargetAssetID.IsSet() {
smap.AddNotNil("target_asset_id", params.TargetAssetID.Value)
}
return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusUploading}, smap)
}

View File

@@ -0,0 +1,2 @@
[registries.strafesnet]
index = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"

1979
releaser/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

11
releaser/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "releaser"
version = "0.1.0"
edition = "2021"
[dependencies]
submissions-api = { version = "0.1.0", registry = "strafesnet" }
rbx_asset = { version = "0.2.5", registry = "strafesnet" }
rust-grpc = { version = "1.0.3", registry = "strafesnet" }
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread", "signal"] }
tonic = "0.12.3"

24
releaser/Containerfile Normal file
View File

@@ -0,0 +1,24 @@
# Using the `rust-musl-builder` as base image, instead of
# the official Rust toolchain
FROM docker.io/clux/muslrust:stable AS chef
USER root
RUN cargo install cargo-chef
WORKDIR /app
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
# Notice that we are specifying the --target flag!
RUN cargo chef cook --release --target x86_64-unknown-linux-musl --recipe-path recipe.json
COPY . .
RUN cargo build --release --target x86_64-unknown-linux-musl --bin releaser
FROM docker.io/alpine:latest AS runtime
RUN addgroup -S myuser && adduser -S myuser -G myuser
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/releaser /usr/local/bin/
USER myuser
ENTRYPOINT ["/usr/local/bin/releaser"]

32
releaser/src/main.rs Normal file
View File

@@ -0,0 +1,32 @@
#[allow(dead_code)]
#[derive(Debug)]
pub enum StartupError{
API(submissions_api::ReqwestError),
GRPCConnect(tonic::transport::Error),
}
impl std::fmt::Display for StartupError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for StartupError{}
// annoying mile-long type
pub type MapsServiceClient=rust_grpc::maps::maps_service_client::MapsServiceClient<tonic::transport::channel::Channel>;
#[tokio::main]
async fn main()->Result<(),StartupError>{
// maps-service api
let api_host=std::env::var("API_HOST").expect("API_HOST env required");
let api=submissions_api::Context::new(api_host).map_err(StartupError::API)?;
// data-service grpc for creating map entries
let data_host=std::env::var("DATA_HOST").expect("DATA_HOST env required");
let maps_grpc=crate::MapsServiceClient::connect(data_host).await.map_err(StartupError::GRPCConnect)?;
// request maps pending release
// randomize list
// release maps
Ok(())
}

View File

@@ -895,17 +895,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -963,12 +952,11 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "submissions-api"
version = "0.3.0"
version = "0.1.0"
dependencies = [
"reqwest",
"serde",
"serde_json",
"serde_repr",
"url",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "submissions-api"
version = "0.3.0"
version = "0.1.0"
edition = "2021"
publish = ["strafesnet"]
repository = "https://git.itzana.me/StrafesNET/maps-service"
@@ -14,10 +14,4 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
reqwest = { version = "0", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_repr = "0.1.19"
url = "2"
[features]
default = ["internal"]
internal = []
external = []

View File

@@ -0,0 +1,131 @@
#[derive(Debug)]
pub enum Error{
ParseError(url::ParseError),
Reqwest(reqwest::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{}
#[derive(serde::Deserialize)]
pub struct ScriptID(i64);
#[allow(nonstandard_style)]
pub struct GetScriptRequest{
pub ScriptID:ScriptID,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptResponse{
pub ID:i64,
pub Hash:String,
pub Source:String,
pub SubmissionID:i64,
}
#[derive(serde::Deserialize)]
#[repr(i32)]
pub enum Policy{
None=0, // not yet reviewed
Allowed=1,
Blocked=2,
Delete=3,
Replace=4,
}
pub struct ScriptPolicyHashRequest{
pub hash:String,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptPolicyResponse{
pub ID:i64,
pub FromScriptHash:String,
pub ToScriptID:ScriptID,
pub Policy:Policy
}
#[allow(nonstandard_style)]
pub struct UpdateSubmissionModelRequest{
pub ID:i64,
pub ModelID:u64,
pub ModelVersion:u64,
}
pub struct SubmissionID(pub i64);
#[derive(Clone)]
pub struct Context{
base_url:String,
client:reqwest::Client,
}
pub type ReqwestError=reqwest::Error;
// there are lots of action endpoints and they all follow the same pattern
macro_rules! action{
($fname:ident,$action:expr)=>{
pub async fn $fname(&self,config:SubmissionID)->Result<(),Error>{
let url_raw=format!(concat!("{}/submissions/{}/status/",$action),self.base_url,config.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
self.post(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?;
Ok(())
}
};
}
impl Context{
pub fn new(mut base_url:String)->reqwest::Result<Self>{
base_url+="/v1";
Ok(Self{
base_url,
client:reqwest::Client::new(),
})
}
async fn get(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.get(url)
.send().await
}
async fn post(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.send().await
}
pub async fn get_script(&self,config:GetScriptRequest)->Result<ScriptResponse,Error>{
let url_raw=format!("{}/scripts/{}",self.base_url,config.ScriptID.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
self.get(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?
.json().await.map_err(Error::Reqwest)
}
pub async fn get_script_policy_from_hash(&self,config:ScriptPolicyHashRequest)->Result<ScriptPolicyResponse,Error>{
let url_raw=format!("{}/script-policy/hash/{}",self.base_url,config.hash);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
self.get(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?
.json().await.map_err(Error::Reqwest)
}
pub async fn update_submission_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{
let url_raw=format!("{}/submissions/{}/model",self.base_url,config.ID);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::ParseError)?;
{
url.query_pairs_mut()
.append_pair("ModelID",config.ModelID.to_string().as_str())
.append_pair("ModelVersion",config.ModelVersion.to_string().as_str());
}
self.post(url).await.map_err(Error::Reqwest)?
.error_for_status().map_err(Error::Reqwest)?;
Ok(())
}
action!(action_submission_validate,"validator-validated");
action!(action_submission_publish,"validator-published");
}

5
validation/Cargo.lock generated
View File

@@ -1804,12 +1804,13 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "submissions-api"
version = "0.3.0"
version = "0.1.0"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "7969c6c0b770ecfb57220c340f732d62a6fb1165b9ef038e33e7cd5a9658bdd5"
dependencies = [
"reqwest",
"serde",
"serde_json",
"serde_repr",
"url",
]

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
submissions-api = { path = "api", features = ["internal"], registry = "strafesnet" }
submissions-api = { version = "0.1.0", registry = "strafesnet" }
async-nats = "0.38.0"
futures = "0.3.31"
rbx_asset = { version = "0.2.5", registry = "strafesnet" }

View File

@@ -11,7 +11,7 @@ RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
COPY api ./api
# Notice that we are specifying the --target flag!
RUN cargo chef cook --release --target x86_64-unknown-linux-musl --recipe-path recipe.json
COPY . .

View File

@@ -1,48 +0,0 @@
pub struct Cookie(reqwest::header::HeaderValue);
impl Cookie{
/// cookie is prepended with "session_id=" by this function
pub fn new(cookie:&str)->Result<Self,reqwest::header::InvalidHeaderValue>{
Ok(Self(reqwest::header::HeaderValue::from_str(&format!("session_id={}",cookie))?))
}
}
#[derive(Clone)]
pub struct Context{
pub base_url:String,
client:reqwest::Client,
}
impl Context{
pub fn new(mut base_url:String,cookie:Option<Cookie>)->reqwest::Result<Self>{
base_url+="/v1";
Ok(Self{
base_url,
client:{
let mut builder=reqwest::ClientBuilder::new();
if let Some(mut cookie)=cookie{
cookie.0.set_sensitive(true);
let mut headers=reqwest::header::HeaderMap::new();
headers.insert("Cookie",cookie.0);
builder=builder.default_headers(headers);
}
builder.build()?
},
})
}
pub async fn get(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.get(url)
.send().await
}
#[cfg(feature="internal")]
pub async fn post_empty_body(&self,url:impl reqwest::IntoUrl)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.send().await
}
pub async fn post(&self,url:impl reqwest::IntoUrl,body:impl Into<reqwest::Body>)->Result<reqwest::Response,reqwest::Error>{
self.client.post(url)
.header("Content-Type","application/json")
.body(body)
.send().await
}
}

View File

@@ -1,131 +0,0 @@
use crate::types::*;
#[derive(Clone)]
pub struct Context(crate::context::Context);
impl Context{
pub fn new(base_url:String,cookie:crate::context::Cookie)->reqwest::Result<Self>{
Ok(Self(crate::context::Context::new(base_url,Some(cookie))?))
}
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::Reqwest)
}
pub async fn get_scripts<'a>(&self,config:GetScriptsRequest<'a>)->Result<Vec<ScriptResponse>,Error>{
let url_raw=format!("{}/scripts",self.0.base_url);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
{
let mut query_pairs=url.query_pairs_mut();
query_pairs.append_pair("Page",config.Page.to_string().as_str());
query_pairs.append_pair("Limit",config.Limit.to_string().as_str());
if let Some(name)=config.Name{
query_pairs.append_pair("Name",name);
}
if let Some(hash)=config.Hash{
query_pairs.append_pair("Hash",hash);
}
if let Some(source)=config.Source{
query_pairs.append_pair("Source",source);
}
if let Some(submission_id)=config.SubmissionID{
query_pairs.append_pair("SubmissionID",submission_id.to_string().as_str());
}
}
response_ok(
self.0.get(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?
.json().await.map_err(Error::Reqwest)
}
pub async fn get_script_from_hash<'a>(&self,config:HashRequest<'a>)->Result<Option<ScriptResponse>,SingleItemError>{
let scripts=self.get_scripts(GetScriptsRequest{
Page:1,
Limit:2,
Hash:Some(config.hash),
Name:None,
Source:None,
SubmissionID:None,
}).await.map_err(SingleItemError::Other)?;
if 1<scripts.len(){
return Err(SingleItemError::DuplicateItems);
}
Ok(scripts.into_iter().next())
}
pub async fn create_script<'a>(&self,config:CreateScriptRequest<'a>)->Result<ScriptIDResponse,Error>{
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::Reqwest)
}
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::Reqwest)
}
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::Reqwest)
}
pub async fn update_script_policy(&self,config:UpdateScriptPolicyRequest)->Result<(),Error>{
let url_raw=format!("{}/script-policy/{}",self.0.base_url,config.ID.0);
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)?;
Ok(())
}
}

View File

@@ -1,126 +0,0 @@
use crate::types::*;
#[derive(Clone)]
pub struct Context(crate::context::Context);
// there are lots of action endpoints and they all follow the same pattern
macro_rules! action{
($fname:ident,$action:expr)=>{
pub async fn $fname(&self,config:SubmissionID)->Result<(),Error>{
let url_raw=format!(concat!("{}/submissions/{}/status/",$action),self.0.base_url,config.0);
let url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
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::Reqwest)
}
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::Reqwest)
}
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::Reqwest)
}
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::Reqwest)
}
pub async fn update_submission_model(&self,config:UpdateSubmissionModelRequest)->Result<(),Error>{
let url_raw=format!("{}/submissions/{}/model",self.0.base_url,config.SubmissionID);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
{
url.query_pairs_mut()
.append_pair("ModelID",config.ModelID.to_string().as_str())
.append_pair("ModelVersion",config.ModelVersion.to_string().as_str());
}
response_ok(
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
}
pub async fn action_submission_uploaded(&self,config:ActionSubmissionUploadedRequest)->Result<(),Error>{
let url_raw=format!("{}/submissions/{}/status/validator-uploaded",self.0.base_url,config.SubmissionID);
let mut url=reqwest::Url::parse(url_raw.as_str()).map_err(Error::Parse)?;
if let Some(target_asset_id)=config.TargetAssetID{
url.query_pairs_mut()
.append_pair("TargetAssetID",target_asset_id.to_string().as_str());
}
response_ok(
self.0.post_empty_body(url).await.map_err(Error::Reqwest)?
).await.map_err(Error::Response)?;
Ok(())
}
action!(action_submission_validated,"validator-validated");
action!(action_submission_accepted,"validator-failed");
action!(action_submission_released,"releaser-released");
}

View File

@@ -1,15 +0,0 @@
mod context;
pub use context::Cookie;
pub mod types;
#[cfg(feature="internal")]
pub mod internal;
#[cfg(feature="external")]
pub mod external;
//lazy reexports
pub use types::Error;
pub type ReqwestError=reqwest::Error;
pub type CookieError=reqwest::header::InvalidHeaderValue;

View File

@@ -1,180 +0,0 @@
#[derive(Debug)]
pub enum Error{
Parse(url::ParseError),
Reqwest(reqwest::Error),
Response(ResponseError),
JSON(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{}
#[derive(Debug)]
pub enum SingleItemError{
DuplicateItems,
Other(Error),
}
impl std::fmt::Display for SingleItemError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for SingleItemError{}
#[allow(dead_code)]
#[derive(Debug)]
pub struct StatusCodeWithUrlAndBody{
pub status_code:reqwest::StatusCode,
pub url:url::Url,
pub body:String,
}
#[derive(Debug)]
pub enum ResponseError{
Reqwest(reqwest::Error),
StatusCodeWithUrlAndBody(StatusCodeWithUrlAndBody),
}
impl std::fmt::Display for ResponseError{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,"{self:?}")
}
}
impl std::error::Error for ResponseError{}
// lazy function to draw out meaningful info from http response on failure
pub async fn response_ok(response:reqwest::Response)->Result<reqwest::Response,ResponseError>{
let status_code=response.status();
if status_code.is_success(){
Ok(response)
}else{
let url=response.url().to_owned();
let bytes=response.bytes().await.map_err(ResponseError::Reqwest)?;
let body=String::from_utf8_lossy(&bytes).to_string();
Err(ResponseError::StatusCodeWithUrlAndBody(StatusCodeWithUrlAndBody{
status_code,
url,
body,
}))
}
}
#[derive(Clone,Copy,PartialEq,Eq,serde::Serialize,serde::Deserialize)]
pub struct ScriptID(pub(crate)i64);
#[derive(Clone,Copy,serde::Serialize,serde::Deserialize)]
pub struct ScriptPolicyID(pub(crate)i64);
#[allow(nonstandard_style)]
pub struct GetScriptRequest{
pub ScriptID:ScriptID,
}
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct GetScriptsRequest<'a>{
pub Page:u32,
pub Limit:u32,
#[serde(skip_serializing_if="Option::is_none")]
pub Name:Option<&'a str>,
#[serde(skip_serializing_if="Option::is_none")]
pub Hash:Option<&'a str>,
#[serde(skip_serializing_if="Option::is_none")]
pub Source:Option<&'a str>,
#[serde(skip_serializing_if="Option::is_none")]
pub SubmissionID:Option<i64>,
}
pub struct HashRequest<'a>{
pub hash:&'a str,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptResponse{
pub ID:ScriptID,
pub Name:String,
pub Hash:String,
pub Source:String,
pub SubmissionID:i64,
}
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct CreateScriptRequest<'a>{
pub Name:&'a str,
pub Source:&'a str,
#[serde(skip_serializing_if="Option::is_none")]
pub SubmissionID:Option<i64>,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptIDResponse{
pub ID:ScriptID,
}
#[derive(PartialEq,Eq,serde_repr::Serialize_repr,serde_repr::Deserialize_repr)]
#[repr(i32)]
pub enum Policy{
None=0, // not yet reviewed
Allowed=1,
Blocked=2,
Delete=3,
Replace=4,
}
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct GetScriptPoliciesRequest<'a>{
pub Page:u32,
pub Limit:u32,
#[serde(skip_serializing_if="Option::is_none")]
pub FromScriptHash:Option<&'a str>,
#[serde(skip_serializing_if="Option::is_none")]
pub ToScriptID:Option<ScriptID>,
#[serde(skip_serializing_if="Option::is_none")]
pub Policy:Option<Policy>,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptPolicyResponse{
pub ID:ScriptPolicyID,
pub FromScriptHash:String,
pub ToScriptID:ScriptID,
pub Policy:Policy
}
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct CreateScriptPolicyRequest{
pub FromScriptID:ScriptID,
pub ToScriptID:ScriptID,
pub Policy:Policy,
}
#[allow(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ScriptPolicyIDResponse{
pub ID:ScriptPolicyID,
}
#[allow(nonstandard_style)]
#[derive(serde::Serialize)]
pub struct UpdateScriptPolicyRequest{
pub ID:ScriptPolicyID,
#[serde(skip_serializing_if="Option::is_none")]
pub FromScriptID:Option<ScriptID>,
#[serde(skip_serializing_if="Option::is_none")]
pub ToScriptID:Option<ScriptID>,
#[serde(skip_serializing_if="Option::is_none")]
pub Policy:Option<Policy>,
}
#[allow(nonstandard_style)]
pub struct UpdateSubmissionModelRequest{
pub SubmissionID:i64,
pub ModelID:u64,
pub ModelVersion:u64,
}
#[allow(nonstandard_style)]
pub struct ActionSubmissionUploadedRequest{
pub SubmissionID:i64,
pub TargetAssetID:Option<u64>,
}
pub struct SubmissionID(pub i64);

View File

@@ -22,25 +22,19 @@ impl std::fmt::Display for StartupError{
}
impl std::error::Error for StartupError{}
pub const GROUP_STRAFESNET:u64=6980477;
pub const PARALLEL_REQUESTS:usize=16;
#[tokio::main]
async fn main()->Result<(),StartupError>{
let group_id:Option<u64>=match std::env::var("ROBLOX_GROUP_ID"){
Ok(s)=>match s.as_str(){
"None"=>None,
_=>Some(s.parse().expect("ROBLOX_GROUP_ID int parse")),
},
Err(e)=>Err(e).expect("ROBLOX_GROUP_ID env required"),
};
// talk to roblox through STRAFESNET_CI2 account
let cookie=std::env::var("RBXCOOKIE").expect("RBXCOOKIE env required");
let cookie_context=rbx_asset::cookie::CookieContext::new(rbx_asset::cookie::Cookie::new(cookie));
// maps-service api
let api_host_internal=std::env::var("API_HOST_INTERNAL").expect("API_HOST_INTERNAL env required");
let api=submissions_api::internal::Context::new(api_host_internal).map_err(StartupError::API)?;
let api_host=std::env::var("API_HOST").expect("API_HOST env required");
let api=submissions_api::Context::new(api_host).map_err(StartupError::API)?;
// nats
let nats_host=std::env::var("NATS_HOST").expect("NATS_HOST env required");
@@ -58,7 +52,7 @@ async fn main()->Result<(),StartupError>{
.messages().await.map_err(StartupError::NatsStream)
};
let message_handler=message_handler::MessageHandler::new(cookie_context,group_id,api);
let message_handler=message_handler::MessageHandler::new(cookie_context,api);
// Create a signal listener for SIGTERM
let mut sig_term=tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()).expect("Failed to create SIGTERM signal listener");

View File

@@ -3,7 +3,6 @@
pub enum HandleMessageError{
Messages(async_nats::jetstream::consumer::pull::MessagesError),
DoubleAck(async_nats::Error),
Json(serde_json::Error),
UnknownSubject(String),
PublishNew(crate::publish_new::PublishError),
PublishFix(crate::publish_fix::PublishError),
@@ -18,10 +17,6 @@ impl std::error::Error for HandleMessageError{}
pub type MessageResult=Result<async_nats::jetstream::Message,async_nats::jetstream::consumer::pull::MessagesError>;
fn from_slice<'a,T:serde::de::Deserialize<'a>>(slice:&'a [u8])->Result<T,HandleMessageError>{
serde_json::from_slice(slice).map_err(HandleMessageError::Json)
}
pub struct MessageHandler{
publish_new:crate::publish_new::Publisher,
publish_fix:crate::publish_fix::Publisher,
@@ -31,12 +26,11 @@ pub struct MessageHandler{
impl MessageHandler{
pub fn new(
cookie_context:rbx_asset::cookie::CookieContext,
group_id:Option<u64>,
api:submissions_api::internal::Context,
api:submissions_api::Context,
)->Self{
Self{
publish_new:crate::publish_new::Publisher::new(cookie_context.clone(),group_id,api.clone()),
publish_fix:crate::publish_fix::Publisher::new(cookie_context.clone(),group_id,api.clone()),
publish_new:crate::publish_new::Publisher::new(cookie_context.clone(),api.clone()),
publish_fix:crate::publish_fix::Publisher::new(cookie_context.clone(),api.clone()),
validator:crate::validator::Validator::new(cookie_context,api),
}
}
@@ -44,9 +38,9 @@ impl MessageHandler{
let message=message_result.map_err(HandleMessageError::Messages)?;
message.double_ack().await.map_err(HandleMessageError::DoubleAck)?;
match message.subject.as_str(){
"maptest.submissions.publishnew"=>self.publish_new.publish(from_slice(&message.payload)?).await.map_err(HandleMessageError::PublishNew),
"maptest.submissions.publishfix"=>self.publish_fix.publish(from_slice(&message.payload)?).await.map_err(HandleMessageError::PublishFix),
"maptest.submissions.validate"=>self.validator.validate(from_slice(&message.payload)?).await.map_err(HandleMessageError::Validation),
"maptest.submissions.publishnew"=>self.publish_new.publish(message).await.map_err(HandleMessageError::PublishNew),
"maptest.submissions.publishfix"=>self.publish_fix.publish(message).await.map_err(HandleMessageError::PublishFix),
"maptest.submissions.validate"=>self.validator.validate(message).await.map_err(HandleMessageError::Validation),
other=>Err(HandleMessageError::UnknownSubject(other.to_owned()))
}
}

View File

@@ -21,7 +21,10 @@ pub struct PublishNewRequest{
pub SubmissionID:i64,
pub ModelID:u64,
pub ModelVersion:u64,
pub ModelName:String,
pub Creator:String,
pub DisplayName:String,
pub GameID:u32,
//games:HashSet<GameID>,
}
#[allow(nonstandard_style)]

View File

@@ -6,7 +6,7 @@ pub enum PublishError{
Get(rbx_asset::cookie::GetError),
Json(serde_json::Error),
Upload(rbx_asset::cookie::UploadError),
ApiActionSubmissionUploaded(submissions_api::Error),
ApiActionSubmissionPublish(submissions_api::Error),
}
impl std::fmt::Display for PublishError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -17,22 +17,23 @@ impl std::error::Error for PublishError{}
pub struct Publisher{
roblox_cookie:rbx_asset::cookie::CookieContext,
group_id:Option<u64>,
api_internal:submissions_api::internal::Context,
api:submissions_api::Context,
}
impl Publisher{
pub const fn new(
roblox_cookie:rbx_asset::cookie::CookieContext,
group_id:Option<u64>,
api_internal:submissions_api::internal::Context,
api:submissions_api::Context,
)->Self{
Self{
roblox_cookie,
group_id,
api_internal,
api,
}
}
pub async fn publish(&self,publish_info:PublishFixRequest)->Result<(),PublishError>{
pub async fn publish(&self,message:async_nats::jetstream::Message)->Result<(),PublishError>{
println!("publish_fix {:?}",message.message.payload);
// decode json
let publish_info:PublishFixRequest=serde_json::from_slice(&message.payload).map_err(PublishError::Json)?;
// download the map model version
let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
asset_id:publish_info.ModelID,
@@ -42,7 +43,7 @@ impl Publisher{
// upload the map to the strafesnet group
let _upload_response=self.roblox_cookie.upload(rbx_asset::cookie::UploadRequest{
assetid:publish_info.TargetAssetID,
groupId:self.group_id,
groupId:Some(crate::GROUP_STRAFESNET),
name:None,
description:None,
ispublic:None,
@@ -51,11 +52,10 @@ impl Publisher{
// that's it, the database entry does not need to be changed.
// mark submission as uploaded, TargetAssetID is unchanged
self.api_internal.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
SubmissionID:publish_info.SubmissionID,
TargetAssetID:None,
}).await.map_err(PublishError::ApiActionSubmissionUploaded)?;
// mark submission as published
self.api.action_submission_publish(
submissions_api::SubmissionID(publish_info.SubmissionID)
).await.map_err(PublishError::ApiActionSubmissionPublish)?;
Ok(())
}

View File

@@ -18,22 +18,23 @@ impl std::error::Error for PublishError{}
pub struct Publisher{
roblox_cookie:rbx_asset::cookie::CookieContext,
group_id:Option<u64>,
api:submissions_api::internal::Context,
api:submissions_api::Context,
}
impl Publisher{
pub const fn new(
roblox_cookie:rbx_asset::cookie::CookieContext,
group_id:Option<u64>,
api:submissions_api::internal::Context,
api:submissions_api::Context,
)->Self{
Self{
roblox_cookie,
group_id,
api,
}
}
pub async fn publish(&self,publish_info:PublishNewRequest)->Result<(),PublishError>{
pub async fn publish(&self,message:async_nats::jetstream::Message)->Result<(),PublishError>{
println!("publish_new {:?}",message.message.payload);
// decode json
let publish_info:PublishNewRequest=serde_json::from_slice(&message.payload).map_err(PublishError::Json)?;
// download the map model version
let model_data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
asset_id:publish_info.ModelID,
@@ -42,18 +43,17 @@ impl Publisher{
// upload the map to the strafesnet group
let upload_response=self.roblox_cookie.create(rbx_asset::cookie::CreateRequest{
name:publish_info.ModelName.clone(),
name:publish_info.DisplayName.clone(),
description:"".to_owned(),
ispublic:false,
allowComments:false,
groupId:self.group_id,
groupId:Some(crate::GROUP_STRAFESNET),
},model_data).await.map_err(PublishError::Create)?;
// note the asset id of the created model for later release, and mark the submission as uploaded
self.api.action_submission_uploaded(submissions_api::types::ActionSubmissionUploadedRequest{
SubmissionID:publish_info.SubmissionID,
TargetAssetID:Some(upload_response.AssetId),
}).await.map_err(PublishError::ApiActionSubmissionPublish)?;
// mark submission as published
self.api.action_submission_publish(
submissions_api::SubmissionID(publish_info.SubmissionID)
).await.map_err(PublishError::ApiActionSubmissionPublish)?;
Ok(())
}

View File

@@ -12,27 +12,16 @@ enum Policy{
Replace(String),
}
struct NamePolicy{
name:String,
policy:Policy,
}
fn source_has_illegal_keywords(source:&str)->bool{
source.find("getfenv").is_some()||source.find("require").is_some()
}
#[allow(dead_code)]
#[derive(Debug)]
pub enum ValidateError{
Flagged,
Blocked,
NotAllowed,
Get(rbx_asset::cookie::GetError),
Json(serde_json::Error),
ReadDom(ReadDomError),
ApiGetScriptPolicy(submissions_api::types::SingleItemError),
ApiGetScriptPolicy(submissions_api::Error),
ApiGetScript(submissions_api::Error),
ApiCreateScript(submissions_api::Error),
ApiCreateScriptPolicy(submissions_api::Error),
ApiUpdateSubmissionModel(submissions_api::Error),
ApiActionSubmissionValidate(submissions_api::Error),
WriteDom(rbx_binary::EncodeError),
@@ -48,42 +37,24 @@ impl std::error::Error for ValidateError{}
pub struct Validator{
roblox_cookie:rbx_asset::cookie::CookieContext,
api:submissions_api::internal::Context,
api:submissions_api::Context,
}
impl Validator{
pub const fn new(
roblox_cookie:rbx_asset::cookie::CookieContext,
api:submissions_api::internal::Context,
api:submissions_api::Context,
)->Self{
Self{
roblox_cookie,
api,
}
}
pub async fn validate(&self,validate_info:ValidateRequest)->Result<(),ValidateError>{
let submission_id=validate_info.SubmissionID;
let validate_result=self.validate_inner(validate_info).await;
pub async fn validate(&self,message:async_nats::jetstream::Message)->Result<(),ValidateError>{
println!("validate {:?}",message.message.payload);
// decode json
let validate_info:ValidateRequest=serde_json::from_slice(&message.payload).map_err(ValidateError::Json)?;
// update the submission depending on the result
match &validate_result{
Ok(())=>{
// update the submission model status to validated
self.api.action_submission_validated(
submissions_api::types::SubmissionID(submission_id)
).await.map_err(ValidateError::ApiActionSubmissionValidate)?;
},
Err(_)=>{
// update the submission model status to accepted
self.api.action_submission_accepted(
submissions_api::types::SubmissionID(submission_id)
).await.map_err(ValidateError::ApiActionSubmissionValidate)?;
},
}
validate_result
}
pub async fn validate_inner(&self,validate_info:ValidateRequest)->Result<(),ValidateError>{
// download map
let data=self.roblox_cookie.get_asset(rbx_asset::cookie::GetAssetRequest{
asset_id:validate_info.ModelID,
@@ -97,78 +68,52 @@ impl Validator{
// collect unique scripts
let script_refs=get_script_refs(&dom);
let mut script_map=std::collections::HashMap::<String,NamePolicy>::new();
let mut script_map=std::collections::HashMap::<String,Policy>::new();
for &script_ref in &script_refs{
if let Some(script)=dom.get_by_ref(script_ref){
if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get("Source"){
// check the source for illegal keywords
if source_has_illegal_keywords(source){
// immediately abort
return Err(ValidateError::Flagged);
}
// associate a name and policy with the source code
// policy will be fetched from the database to replace the default policy
script_map.insert(source.clone(),NamePolicy{
name:script.name.clone(),
policy:Policy::None,
});
script_map.insert(source.clone(),Policy::None);
}
}
}
// send all script hashes to REST endpoint and retrieve the replacements
futures::stream::iter(script_map.iter_mut().map(Ok))
.try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,NamePolicy{policy,name})|async{
.try_for_each_concurrent(Some(SCRIPT_CONCURRENCY),|(source,replacement)|async{
// get the hash
let mut hasher=siphasher::sip::SipHasher::new();
std::hash::Hasher::write(&mut hasher,source.as_bytes());
let hash=std::hash::Hasher::finish(&hasher);
// fetch the script policy
let script_policy=self.api.get_script_policy_from_hash(submissions_api::types::HashRequest{
hash:format!("{:016x}",hash).as_str(),
let script_policy=self.api.get_script_policy_from_hash(submissions_api::ScriptPolicyHashRequest{
hash:format!("{:x}",hash),
}).await.map_err(ValidateError::ApiGetScriptPolicy)?;
// write the policy to the script_map, fetching the replacement code if necessary
if let Some(script_policy)=script_policy{
*policy=match script_policy.Policy{
submissions_api::types::Policy::None=>Policy::None,
submissions_api::types::Policy::Allowed=>Policy::Allowed,
submissions_api::types::Policy::Blocked=>Policy::Blocked,
submissions_api::types::Policy::Delete=>Policy::Delete,
submissions_api::types::Policy::Replace=>{
let script=self.api.get_script(submissions_api::types::GetScriptRequest{
ScriptID:script_policy.ToScriptID,
}).await.map_err(ValidateError::ApiGetScript)?;
Policy::Replace(script.Source)
},
};
}else{
// upload the script
let script=self.api.create_script(submissions_api::types::CreateScriptRequest{
Name:name.as_str(),
Source:source.as_str(),
SubmissionID:Some(validate_info.SubmissionID),
}).await.map_err(ValidateError::ApiCreateScript)?;
// create a None policy (pending review by yours truly)
self.api.create_script_policy(submissions_api::types::CreateScriptPolicyRequest{
ToScriptID:script.ID,
FromScriptID:script.ID,
Policy:submissions_api::types::Policy::None,
}).await.map_err(ValidateError::ApiCreateScriptPolicy)?;
}
*replacement=match script_policy.Policy{
submissions_api::Policy::None=>Policy::None,
submissions_api::Policy::Allowed=>Policy::Allowed,
submissions_api::Policy::Blocked=>Policy::Blocked,
submissions_api::Policy::Delete=>Policy::Delete,
submissions_api::Policy::Replace=>{
let script=self.api.get_script(submissions_api::GetScriptRequest{
ScriptID:script_policy.ToScriptID,
}).await.map_err(ValidateError::ApiGetScript)?;
Policy::Replace(script.Source)
},
};
Ok(())
})
.await?;
// make the replacements
let mut modified=true;
let mut modified=false;
for &script_ref in &script_refs{
if let Some(script)=dom.get_by_ref_mut(script_ref){
if let Some(rbx_dom_weak::types::Variant::String(source))=script.properties.get_mut("Source"){
match script_map.get(source.as_str()).map(|p|&p.policy){
match script_map.get(source.as_str()){
Some(Policy::Blocked)=>return Err(ValidateError::Blocked),
None
|Some(Policy::None)
@@ -188,8 +133,6 @@ impl Validator{
}
}
println!("[Validator] Forcing model upload! modified=true");
// if the model was validated, the submission must be changed to use the modified model
if modified{
// serialize model (slow!)
@@ -223,13 +166,18 @@ impl Validator{
};
// update the submission to use the validated model
self.api.update_submission_model(submissions_api::types::UpdateSubmissionModelRequest{
SubmissionID:validate_info.SubmissionID,
self.api.update_submission_model(submissions_api::UpdateSubmissionModelRequest{
ID:validate_info.SubmissionID,
ModelID:model_id,
ModelVersion:1, //TODO
}).await.map_err(ValidateError::ApiUpdateSubmissionModel)?;
};
// update the submission model status to validated
self.api.action_submission_validate(
submissions_api::SubmissionID(validate_info.SubmissionID)
).await.map_err(ValidateError::ApiActionSubmissionValidate)?;
Ok(())
}
}

View File

@@ -6,22 +6,11 @@ const nextConfig: NextConfig = {
rewrites: async () => {
return [
{
source: "/api/:path*",
destination: "http://localhost:8082/v1/:path*"
source: "/v1/submissions/:submissionid/status/:statustype",
destination: "http://mapsservice:8082/v1/submissions/:submissionid/status/:statustype"
}
]
},
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'api.ic3.space',
pathname: '/strafe/map-images/**',
port: '',
search: '',
},
],
},
}
};
export default nextConfig;

View File

@@ -18,10 +18,10 @@ export default function Header() {
return (
<header className="header-bar">
<nav className="left">
<HeaderButton name="Submissions" href="/submissions"/>
<HeaderButton name="Maps" href=""/>
</nav>
<nav className="right">
<HeaderButton name="Submit" href="/submit"/>
<HeaderButton name="Home" href=""/>
<HeaderButton name="Need" href=""/>
<HeaderButton name="Menu" href=""/>
<HeaderButton name="Items" href=""/>

View File

@@ -2,8 +2,8 @@
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: var(--header-height);
width: 100vw;
height: 60px;
background: var(--header-grad-left);
background: linear-gradient(180deg, var(--header-grad-left) 0%, var(--header-grad-right) 100%);
@@ -24,7 +24,7 @@
.right {
display: flex;
gap: 7px;
margin-right: 35px;
margin-right: 50px;
button {
font-size: 1rem;

View File

@@ -10,8 +10,6 @@ $form-label-fontsize: 1.3rem;
:root {
color-scheme: light dark;
--header-height: 60px;
--page: white;
--header-grad-left: #363b40;
--header-grad-right: #353a40;

View File

@@ -1,24 +0,0 @@
@forward "./page/card.scss";
@use "../../globals.scss";
.container {
display: flex;
justify-content: center;
align-items: center;
height: calc(100vh - var(--header-height));
overflow: hidden;
position: relative;
}
a {
color:rgb(255, 255, 255);
&:visited, &:hover, &:focus {
text-decoration: none;
color: rgb(255, 255, 255);
}
&:active {
color: rgb(192, 192, 192)
}
}

View File

@@ -1,12 +0,0 @@
@use "../../../globals.scss";
.submissionCard {
@include globals.border-with-radius;
background-color: #2020207c;
border: 1px solid #501717;
border-radius: 6px;
padding: 6px;
text-align: center;
font-size: 14px;
}

View File

@@ -1,13 +1,12 @@
$UnderConstruction: "0";
$Submitted: "1";
$ChangesRequested: "2";
$Accepted: "3";
$Published: "0";
$Rejected: "1";
$Publishing: "2";
$Validated: "3";
$Validating: "4";
$Validated: "5";
$Uploading: "6";
$Uploaded: "7";
$Rejected: "8";
$Released: "9";
$Accepted: "5";
$ChangesRequested: "6";
$Submitted: "7";
$UnderConstruction: "8";
.review-status {
border-radius: 5px;
@@ -17,7 +16,7 @@ $Released: "9";
font-weight: bold;
}
&[data-review-status="#{$Released}"] {
&[data-review-status="#{$Published}"] {
background-color: orange;
p {
color: white;
@@ -29,13 +28,7 @@ $Released: "9";
color: white;
}
}
&[data-review-status="#{$Uploading}"] {
background-color: orange;
p {
color: white;
}
}
&[data-review-status="#{$Uploaded}"] {
&[data-review-status="#{$Publishing}"] {
background-color: orange;
p {
color: white;
@@ -77,4 +70,4 @@ $Released: "9";
color: white;
}
}
}
}

View File

@@ -9,7 +9,6 @@ interface CommentersProps {
}
interface CreatorAndReviewStatus {
asset_id: SubmissionInfo["AssetID"],
creator: SubmissionInfo["DisplayName"],
review: SubmissionInfo["StatusID"],
comments: Comment[],
@@ -64,4 +63,4 @@ export default function Comments(stats: CommentersProps) {
export {
type CreatorAndReviewStatus
}
}

View File

@@ -1,54 +1,36 @@
import { Button, ButtonOwnProps } from "@mui/material";
import { SubmissionInfo } from "@/app/ts/Submission";
type Actions = "Completed" | "Submit" | "Reject" | "Revoke"
type Review = Actions | "Accept" | "Validate" | "Upload"
type Action = Lowercase<Actions> | "trigger-validate" | "trigger-upload"
type Review = "Completed" | "Submit" | "Reject" | "Revoke" | "Accept" | "Validate" | "Upload"
type Action = "completed" | "submit" | "reject" | "revoke" | "trigger-validate" | "trigger-upload"
interface ReviewButton {
name: Review,
action: Action,
submissionId: string,
color: ButtonOwnProps["color"]
}
function ReviewButtonClicked(action: Action, submissionId: string) {
fetch(`/api/submissions/${submissionId}/status/${action}`, {
function ReviewButtonClicked(action: Action) {
fetch(`http://localhost:3000/v1/submissions/1/status/${action}`, {
method: "POST",
headers: {
"Content-type": "application/json",
}
}).then(() => { window.location.reload(); })
})
}
function ReviewButton(props: ReviewButton) {
return <Button
color={props.color}
variant="contained"
onClick={() => { ReviewButtonClicked(props.action, props.submissionId) }}>{props.name}</Button>
return <Button color={props.color} variant="contained" onClick={() => { ReviewButtonClicked(props.action) }}>{props.name}</Button>
}
export default function ReviewButtons(props: SubmissionInfo) {
const submissionId = props.ID.toString()
// When is each button visible?
// Multiple buttons can be visible at once.
// Action | Role | When Current Status is One of:
// ---------------|-----------|-----------------------
// Submit | Submitter | UnderConstruction, ChangesRequested
// Revoke | Submitter | Submitted, ChangesRequested
// Accept | Reviewer | Submitted
// Validate | Reviewer | Accepted
// Reject | Reviewer | Submitted
// RequestChanges | Reviewer | Validated, Accepted, Submitted
// Upload | MapAdmin | Validated
export default function ReviewButtons() {
return (
<section className="review-set">
<ReviewButton color="info" name="Submit" action="submit" submissionId={submissionId}/>
<ReviewButton color="info" name="Revoke" action="revoke" submissionId={submissionId}/>
<ReviewButton color="info" name="Accept" action="trigger-validate" submissionId={submissionId}/>
<ReviewButton color="info" name="Validate" action="trigger-validate" submissionId={submissionId}/>
<ReviewButton color="error" name="Reject" action="reject" submissionId={submissionId}/>
<ReviewButton color="info" name="Upload" action="trigger-upload" submissionId={submissionId}/>
<ReviewButton color="info" name="Submit" action="submit"/>
<ReviewButton color="info" name="Revoke" action="revoke"/>
<ReviewButton color="info" name="Accept" action="trigger-validate"/>
<ReviewButton color="info" name="Validate" action="trigger-validate"/>
<ReviewButton color="error" name="Reject" action="reject"/>
<ReviewButton color="info" name="Upload" action="trigger-upload"/>
<ReviewButton color="info" name="Completed" action="completed"/>
</section>
)
}

View File

@@ -1,6 +1,6 @@
"use client"
import { SubmissionInfo, SubmissionStatusToString } from "@/app/ts/Submission";
import { SubmissionStatus, SubmissionStatusToString } from "@/app/ts/Submission";
import type { CreatorAndReviewStatus } from "./_comments";
import { MapImage } from "./_map";
import { useParams } from "next/navigation";
@@ -10,7 +10,6 @@ import Comments from "./_comments";
import Webpage from "@/app/_components/webpage";
import Window from "./_window";
import Link from "next/link";
import { useState, useEffect } from "react";
import "./(styles)/page.scss";
@@ -35,15 +34,14 @@ function Ratings() {
)
}
function RatingArea(submission: SubmissionInfo) {
function RatingArea() {
return (
<aside className="review-area">
<section className="map-image-area">
<MapImage/>
</section>
<Ratings/>
{/* TODO: NOT DO!!! */} {ReviewButtons(submission)}
{/* <ReviewButtons submissionId={submission.ID}/> */}
<ReviewButtons/>
</aside>
)
}
@@ -60,7 +58,6 @@ function TitleAndComments(stats: CreatorAndReviewStatus) {
</aside>
</div>
<p className="by-creator">by <Link href="" target="_blank">{stats.creator}</Link></p>
<p className="asset-id">Model Asset ID {stats.asset_id}</p>
<span className="spacer"></span>
<Comments comments_data={stats}/>
</main>
@@ -70,31 +67,14 @@ function TitleAndComments(stats: CreatorAndReviewStatus) {
export default function SubmissionInfoPage() {
const dynamicId = useParams<{submissionId: string}>()
const [submission, setSubmission] = useState<SubmissionInfo | null>(null)
useEffect(() => { // needs to be client sided since server doesn't have a session, nextjs got mad at me for exporting an async function: (https://nextjs.org/docs/messages/no-async-client-component)
async function getSubmission() {
const res = await fetch(`/api/submissions/${dynamicId.submissionId}`)
if (res.ok) {
setSubmission(await res.json())
}
}
getSubmission()
}, [dynamicId.submissionId])
if (!submission) {
return <Webpage>
{/* TODO: Add skeleton loading thingy ? Maybe ? (https://mui.com/material-ui/react-skeleton/) */}
</Webpage>
}
return (
<Webpage>
<main className="map-page-main">
<section className="review-section">
{RatingArea(submission)}
<TitleAndComments name={submission.DisplayName} creator={submission.Creator} review={submission.StatusID} asset_id={submission.AssetID} comments={[]}/>
<RatingArea/>
<TitleAndComments name={dynamicId.submissionId} creator="Quaternions" review={SubmissionStatus.Accepted} comments={[]}/>
</section>
</main>
</Webpage>
)
}
}

View File

@@ -1,25 +0,0 @@
import React from "react";
import Image from "next/image";
import Link from "next/link";
interface SubmissionCardProps {
displayName: string;
assetId: number;
rating: number;
author: string;
id: number;
}
export default function SubmissionCard(props: SubmissionCardProps) {
return (
<Link href={`/submissions/${props.id}`}>
<div className="submissionCard">
{/* TODO: Grab image of model */}
<Image height={200} width={200} priority={true} src="https://api.ic3.space/strafe/map-images/11222350808" style={{ width: `100%` }} alt={props.displayName} />
<h3>{props.displayName}</h3>
<p>By {props.author}</p>
<p> {props.rating}</p> {/* TODO: paste the star element from submission/1 page */}
</div>
</Link>
);
}

View File

@@ -1,43 +0,0 @@
//This can all be solved using 0 JavaScript,
//display: grid, ->1fr unit<-
import React, { useState, useEffect } from 'react';
import { Grid, Skeleton } from '@mui/material';
const elementWidth = 220;
function calculateSkeletonCount(setState: React.Dispatch<React.SetStateAction<number>>) {
const viewportWidth = window.innerWidth - 100 * 2;
setState(Math.floor(viewportWidth / elementWidth) * 2);
};
function SkeletonGrid() {
const [skeletonCount, setSkeletonCount] = useState(0);
useEffect(() => {
calculateSkeletonCount(setSkeletonCount);
window.addEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
return () => {
window.removeEventListener('resize', () => { calculateSkeletonCount(setSkeletonCount) });
};
}, []);
return (
<Grid
container
spacing={2}
alignItems="center"
justifyContent="center"
style={{ maxWidth: 'calc(100vw - 100px)', margin: '0 auto' }}
>
{Array.from({ length: skeletonCount }).map((_, index) => (
<Grid item key={index}>
<Skeleton variant="rectangular" width={215} height={340} />
</Grid>
))}
</Grid>
);
};
export default SkeletonGrid;

View File

@@ -1,18 +0,0 @@
interface WindowStruct {
children: React.ReactNode,
className: string,
title: string,
}
export default function Window(window: WindowStruct) {
return <section className={window.className}>
<header>
<p>{window.title}</p>
</header>
<main>{window.children}</main>
</section>
}
export {
type WindowStruct
}

View File

@@ -1,77 +0,0 @@
'use client'
import React, { useState, useEffect } from 'react'
import { SubmissionInfo } from '../ts/Submission';
import { Grid2 as Grid } from '@mui/material';
import SubmissionCard from "./_card";
import SkeletonGrid from './_loading';
import Webpage from "@/app/_components/webpage";
import "./(styles)/page.scss";
export default function SubmissionInfoPage() {
const [submissions, setSubmissions] = useState<SubmissionInfo[]>([])
useEffect(() => { // needs to be client sided since server doesn't have a session, nextjs got mad at me for exporting an async function: (https://nextjs.org/docs/messages/no-async-client-component)
async function fetchSubmissions() {
const res = await fetch('/api/submissions?Page=1&Limit=100')
if (res.ok) {
setSubmissions(await res.json())
}
}
setTimeout(() => { // testing loading screen made by chatGerbertPT
fetchSubmissions()
}, 250);
}, [])
if (!submissions) {
return <Webpage>
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
<SkeletonGrid />
</main>
</Webpage>
}
return (
// TODO: Add filter settings & searchbar & page selector
<Webpage>
<main style={{ display: 'flex', justifyContent: 'center', padding: '1rem' }}>
<Grid
container
spacing={2}
alignItems="center"
justifyContent="center"
style={{ maxWidth: 'calc(100vw - 100px)', margin: '0 auto' }}
>
{submissions.map((submission) => (
<Grid key={submission.ID}>
<SubmissionCard
id={submission.ID}
assetId={submission.AssetID}
displayName={submission.DisplayName}
author={submission.Creator}
rating={submission.StatusID}
/>
</Grid>
))}
</Grid>
</main>
</Webpage>
)
// {
// "ID": 1,
// "DisplayName": "81bfc7a",
// "Creator": "79fbe8d",
// "GameID": 1073741824,
// "CreatedAt": 1734490019,
// "UpdatedAt": 1734565641,
// "Submitter": 1,
// "AssetID": 6438937102481093,
// "AssetVersion": 1225679040570074,
// "Completed": false,
// "SubmissionType": 0,
// "TargetAssetID": 1057095197389979,
// "StatusID": 4
// }
}

View File

@@ -25,6 +25,7 @@
}
& fieldset {
border-color: rgb(100,100,100);
}
& span {
color: white;

View File

@@ -1,66 +0,0 @@
import { FormControl, Select, InputLabel, MenuItem } from "@mui/material";
import { styled } from '@mui/material/styles';
import InputBase from '@mui/material/InputBase';
import React from "react";
import { SelectChangeEvent } from "@mui/material";
// TODO: Properly style everything instead of pasting 🤚
type GameSelectionProps = {
game: number;
setGame: React.Dispatch<React.SetStateAction<number>>;
};
const BootstrapInput = styled(InputBase)(({ theme }) => ({
'label + &': {
marginTop: theme.spacing(3),
},
'& .MuiInputBase-input': {
backgroundColor: '#0000',
color: '#FFF',
border: '1px solid rgba(175, 175, 175, 0.66)',
fontSize: 16,
padding: '10px 26px 10px 12px',
transition: theme.transitions.create(['border-color', 'box-shadow']),
// Use the system font instead of the default Roboto font.
fontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
].join(','),
'&:focus': {
borderRadius: 4,
borderColor: '#80bdff',
boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)',
},
},
}));
export default function GameSelection({ game, setGame }: GameSelectionProps) {
const handleChange = (event: SelectChangeEvent) => {
setGame(Number(event.target.value)); // TODO: Change later!! there's 100% a proper way of doing this
};
return (
<FormControl>
<InputLabel sx={{ color: "#646464" }}>Game</InputLabel>
<Select
value={String(game)}
label="Game"
onChange={handleChange}
input={<BootstrapInput />}
>
<MenuItem value={1}>Bhop</MenuItem>
<MenuItem value={2}>Surf</MenuItem>
<MenuItem value={3}>Fly Trials</MenuItem>
</Select>
</FormControl>
);
}

View File

@@ -0,0 +1,67 @@
interface FormNumbers {
readonly GameID: number,
readonly AssetID: number,
readonly AssetVersion: number
}
interface FormStrings {
readonly DisplayName: string,
readonly Creator: string,
}
function SubmitAPI(json: string) {
console.log(json)
}
function SafeNumbers(form: FormNumbers): Promise<FormNumbers> {
const form_number_values = [form.GameID, form.AssetID, form.AssetVersion]
return new Promise((resolve, reject) => {
form_number_values.forEach(v => {
if (!Number.isSafeInteger(v)) {
reject(`Form Value: ${v} was not a valid number`)
}
})
resolve(form)
})
}
function SafeStrings(form: FormStrings): Promise<FormStrings> {
const form_string_values = [form.DisplayName, form.Creator]
return new Promise((resolve, reject) => {
form_string_values.forEach(v => {
if (v.length>=128) {
reject(`Form value: ${v} is beyond the max 128 string limit`)
}
})
resolve(form)
})
}
export default function Submit() {
const form_numbers: FormNumbers = {
GameID: Number((document.getElementById("game-id") as HTMLInputElement).value),
AssetID: Number((document.getElementById("asset-id") as HTMLInputElement).value),
AssetVersion: Number((document.getElementById("asset-version") as HTMLInputElement).value),
}
const form_strings: FormStrings = {
DisplayName: (document.getElementById("display-name") as HTMLInputElement).value,
Creator: (document.getElementById("creator") as HTMLInputElement).value
}
const valid_numbers = SafeNumbers(form_numbers)
const valid_strings = SafeStrings(form_strings)
valid_strings.then(form_strings => {
valid_numbers.then(form_numbers => {
SubmitAPI(JSON.stringify({
DisplayName: form_strings.DisplayName,
Creator: form_strings.Creator,
GameID: form_numbers.GameID,
AssetID: form_numbers.AssetID,
AssetVersion: form_numbers.AssetVersion
}))
}).catch(e => console.log(e))
}).catch(e => console.log(e))
}

View File

@@ -1,98 +1,46 @@
"use client"
import { FormControl, FormControlLabel, Button, TextField, Checkbox } from "@mui/material"
import GameSelection from "./_game";
import { FormControl, FormLabel, RadioGroup, FormControlLabel, Button, TextField } from "@mui/material"
import SendIcon from '@mui/icons-material/Send';
import Webpage from "@/app/_components/webpage"
import React, { useState } from "react";
import Submit from "./_submit";
import Radio from '@mui/material/Radio';
import "./(styles)/page.scss"
interface SubmissionPayload {
DisplayName: string;
Creator: string;
GameID: number;
AssetID: number;
AssetVersion: number;
TargetAssetID: number;
}
interface IdResponse {
ID: number;
function TargetAsset() {
return <FormControl>
<FormLabel id="target-asset-radio">Target:</FormLabel>
<RadioGroup defaultValue="New" aria-labelledby="target-asset-radio" name="target-asset-radio">
<FormControlLabel value="New" control={<Radio/>} label="New" id="asset-new"/>
<FormControlLabel value="Fix" control={<Radio/>} label="Fix" id="asset-Fix"/>
</RadioGroup>
</FormControl>
}
export default function SubmissionInfoPage() {
const [game, setGame] = useState(1);
const [isFixingMap, setIsFixingMap] = useState(false);
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);
const payload: SubmissionPayload = {
DisplayName: (formData.get("display-name") as string) ?? "unknown", // TEMPORARY! TODO: Change
Creator: (formData.get("creator") as string) ?? "unknown", // TEMPORARY! TODO: Change
GameID: game,
AssetID: Number((formData.get("asset-id") as string) ?? "0"),
AssetVersion: 0,
TargetAssetID: isFixingMap ? Number((formData.get("target-asset-id") as string) ?? "0") : 0,
};
console.log(payload)
console.log(JSON.stringify(payload))
try {
// Send the POST request
const response = await fetch("/api/submissions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
// Allow any HTTP status
const id_response:IdResponse = await response.json();
// navigate to newly created submission
window.location.assign(`/submissions/${id_response.ID}`)
} catch (error) {
console.error("Error submitting data:", error);
}
};
return (
<Webpage>
<main>
<header>
<h1>Submit Asset</h1>
<span className="spacer form-spacer"></span>
</header>
<form onSubmit={handleSubmit}>
{/* TODO: Add form data for mapfixes, such as changes they did, and any times that need to be deleted & what styles */}
<TextField className="form-field" id="display-name" name="display-name" label="Display Name" variant="outlined"/>
<TextField className="form-field" id="creator" name="creator" label="Creator" variant="outlined"/>
<TextField className="form-field" id="asset-id" name="asset-id" label="Asset ID" variant="outlined"/>
{/* I think this is Quat's job to figure this one out (to be set when someone clicks review(?)) */} {/* <TextField className="form-field" id="asset-version" label="Asset Version" variant="outlined"/> */}
<GameSelection game={game} setGame={setGame} />
<FormControl>
<FormControlLabel control={<Checkbox sx={{
color: "#646464",
'&.Mui-checked': {
color: "#66BB6A",
},
}} onChange={(e) => setIsFixingMap(e.target.checked)} />} label="Fixing an Existing Map?" />
</FormControl>
<TextField className="form-field" id="target-asset-id" name="target-asset-id" label="Target Asset ID (group model)" variant="outlined"/>
<span className="spacer form-spacer"></span>
<Button type="submit" variant="contained" startIcon={<SendIcon/>} sx={{
width: "400px",
height: "50px",
marginInline: "auto"
}}>Submit</Button>
</form>
</main>
</Webpage>
return (
<Webpage>
<main>
<header>
<h1>Submit Asset</h1>
<span className="spacer form-spacer"></span>
</header>
<form>
<TextField className="form-field" id="display-name" label="Display Name" variant="outlined"/>
<TextField className="form-field" id="creator" label="Creator" variant="outlined"/>
<TextField className="form-field" id="game-id" label="Game ID" variant="outlined" type="number"/>
<TextField className="form-field" id="asset-id" label="Asset ID" variant="outlined" type="number"/>
<TextField className="form-field" id="asset-version" label="Asset Version" variant="outlined" type="number"/>
<TargetAsset/>
</form>
<span className="spacer form-spacer"></span>
<Button variant="contained" startIcon={<SendIcon />} onClick={() => { Submit() }} sx={{
width: "400px",
height: "50px",
marginInline: "auto"
}}>Submit</Button>
</main>
</Webpage>
)
}
}

View File

@@ -1,14 +1,13 @@
const enum SubmissionStatus {
UnderConstruction = 0,
Submitted = 1,
ChangesRequested = 2,
Accepted = 3,
Validating = 4,
Validated = 5,
Uploading = 6,
Uploaded = 7,
Rejected = 8,
Released = 9,
Published,
Rejected,
Publishing,
Validated,
Validating,
Accepted,
ChangesRequested,
Submitted,
UnderConstruction
}
interface SubmissionInfo {
@@ -27,14 +26,12 @@ interface SubmissionInfo {
function SubmissionStatusToString(submission_status: SubmissionStatus): string {
switch (submission_status) {
case SubmissionStatus.Released:
return "RELEASED"
case SubmissionStatus.Published:
return "PUBLISHED"
case SubmissionStatus.Rejected:
return "REJECTED"
case SubmissionStatus.Uploading:
return "UPLOADING"
case SubmissionStatus.Uploaded:
return "UPLOADED"
case SubmissionStatus.Publishing:
return "PUBLISHING"
case SubmissionStatus.Validated:
return "VALIDATED"
case SubmissionStatus.Validating:
@@ -56,4 +53,4 @@ export {
SubmissionStatus,
SubmissionStatusToString,
type SubmissionInfo
}
}