diff --git a/pkg/api/oas_client_gen.go b/pkg/api/oas_client_gen.go index 6f6b0a7..f865e3a 100644 --- a/pkg/api/oas_client_gen.go +++ b/pkg/api/oas_client_gen.go @@ -143,6 +143,12 @@ type Invoker interface { // // POST /mapfixes CreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (*OperationID, error) + // CreateMapfixAuditComment invokes createMapfixAuditComment operation. + // + // Post a comment to the audit log. + // + // POST /mapfixes/{MapfixID}/comment + CreateMapfixAuditComment(ctx context.Context, request CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error // CreateScript invokes createScript operation. // // Create a new script. @@ -161,6 +167,12 @@ type Invoker interface { // // POST /submissions CreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (*OperationID, error) + // CreateSubmissionAuditComment invokes createSubmissionAuditComment operation. + // + // Post a comment to the audit log. + // + // POST /submissions/{SubmissionID}/comment + CreateSubmissionAuditComment(ctx context.Context, request CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error // DeleteScript invokes deleteScript operation. // // Delete the specified script by ID. @@ -209,6 +221,12 @@ type Invoker interface { // // GET /submissions/{SubmissionID} GetSubmission(ctx context.Context, params GetSubmissionParams) (*Submission, error) + // ListMapfixAuditEvents invokes listMapfixAuditEvents operation. + // + // Retrieve a list of audit events. + // + // GET /mapfixes/{MapfixID}/audit-events + ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) ([]AuditEvent, error) // ListMapfixes invokes listMapfixes operation. // // Get list of mapfixes. @@ -233,6 +251,12 @@ type Invoker interface { // // GET /scripts ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error) + // ListSubmissionAuditEvents invokes listSubmissionAuditEvents operation. + // + // Retrieve a list of audit events. + // + // GET /submissions/{SubmissionID}/audit-events + ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) ([]AuditEvent, error) // ListSubmissions invokes listSubmissions operation. // // Get list of submissions. @@ -2690,6 +2714,133 @@ func (c *Client) sendCreateMapfix(ctx context.Context, request *MapfixTriggerCre return result, nil } +// CreateMapfixAuditComment invokes createMapfixAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /mapfixes/{MapfixID}/comment +func (c *Client) CreateMapfixAuditComment(ctx context.Context, request CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error { + _, err := c.sendCreateMapfixAuditComment(ctx, request, params) + return err +} + +func (c *Client) sendCreateMapfixAuditComment(ctx context.Context, request CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) (res *CreateMapfixAuditCommentNoContent, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createMapfixAuditComment"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/comment"), + } + + // 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, CreateMapfixAuditCommentOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [3]string + pathParts[0] = "/mapfixes/" + { + // Encode "MapfixID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "MapfixID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.MapfixID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/comment" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateMapfixAuditCommentRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, CreateMapfixAuditCommentOperation, 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 := decodeCreateMapfixAuditCommentResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // CreateScript invokes createScript operation. // // Create a new script. @@ -3014,6 +3165,133 @@ func (c *Client) sendCreateSubmission(ctx context.Context, request *SubmissionTr return result, nil } +// CreateSubmissionAuditComment invokes createSubmissionAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /submissions/{SubmissionID}/comment +func (c *Client) CreateSubmissionAuditComment(ctx context.Context, request CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error { + _, err := c.sendCreateSubmissionAuditComment(ctx, request, params) + return err +} + +func (c *Client) sendCreateSubmissionAuditComment(ctx context.Context, request CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) (res *CreateSubmissionAuditCommentNoContent, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createSubmissionAuditComment"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/comment"), + } + + // 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, CreateSubmissionAuditCommentOperation, + 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] = "/comment" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateSubmissionAuditCommentRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, CreateSubmissionAuditCommentOperation, 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 := decodeCreateSubmissionAuditCommentResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // DeleteScript invokes deleteScript operation. // // Delete the specified script by ID. @@ -3833,6 +4111,129 @@ func (c *Client) sendGetSubmission(ctx context.Context, params GetSubmissionPara return result, nil } +// ListMapfixAuditEvents invokes listMapfixAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /mapfixes/{MapfixID}/audit-events +func (c *Client) ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) ([]AuditEvent, error) { + res, err := c.sendListMapfixAuditEvents(ctx, params) + return res, err +} + +func (c *Client) sendListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) (res []AuditEvent, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("listMapfixAuditEvents"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/audit-events"), + } + + // 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, ListMapfixAuditEventsOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [3]string + pathParts[0] = "/mapfixes/" + { + // Encode "MapfixID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "MapfixID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.MapfixID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/audit-events" + 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") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", 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 := decodeListMapfixAuditEventsResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // ListMapfixes invokes listMapfixes operation. // // Get list of mapfixes. @@ -4589,6 +4990,129 @@ func (c *Client) sendListScripts(ctx context.Context, params ListScriptsParams) return result, nil } +// ListSubmissionAuditEvents invokes listSubmissionAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /submissions/{SubmissionID}/audit-events +func (c *Client) ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) ([]AuditEvent, error) { + res, err := c.sendListSubmissionAuditEvents(ctx, params) + return res, err +} + +func (c *Client) sendListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) (res []AuditEvent, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("listSubmissionAuditEvents"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/audit-events"), + } + + // 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, ListSubmissionAuditEventsOperation, + 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] = "/audit-events" + 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") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", 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 := decodeListSubmissionAuditEventsResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // ListSubmissions invokes listSubmissions operation. // // Get list of submissions. diff --git a/pkg/api/oas_handlers_gen.go b/pkg/api/oas_handlers_gen.go index 7a5dee0..995a780 100644 --- a/pkg/api/oas_handlers_gen.go +++ b/pkg/api/oas_handlers_gen.go @@ -3735,6 +3735,216 @@ func (s *Server) handleCreateMapfixRequest(args [0]string, argsEscaped bool, w h } } +// handleCreateMapfixAuditCommentRequest handles createMapfixAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /mapfixes/{MapfixID}/comment +func (s *Server) handleCreateMapfixAuditCommentRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createMapfixAuditComment"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/comment"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateMapfixAuditCommentOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateMapfixAuditCommentOperation, + ID: "createMapfixAuditComment", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, CreateMapfixAuditCommentOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + 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 { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeCreateMapfixAuditCommentParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + request, close, err := s.decodeCreateMapfixAuditCommentRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CreateMapfixAuditCommentNoContent + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateMapfixAuditCommentOperation, + OperationSummary: "Post a comment to the audit log", + OperationID: "createMapfixAuditComment", + Body: request, + Params: middleware.Parameters{ + { + Name: "MapfixID", + In: "path", + }: params.MapfixID, + }, + Raw: r, + } + + type ( + Request = CreateMapfixAuditCommentReq + Params = CreateMapfixAuditCommentParams + Response = *CreateMapfixAuditCommentNoContent + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackCreateMapfixAuditCommentParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.CreateMapfixAuditComment(ctx, request, params) + return response, err + }, + ) + } else { + err = s.h.CreateMapfixAuditComment(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateMapfixAuditCommentResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleCreateScriptRequest handles createScript operation. // // Create a new script. @@ -4320,6 +4530,216 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool, } } +// handleCreateSubmissionAuditCommentRequest handles createSubmissionAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /submissions/{SubmissionID}/comment +func (s *Server) handleCreateSubmissionAuditCommentRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createSubmissionAuditComment"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/comment"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateSubmissionAuditCommentOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateSubmissionAuditCommentOperation, + ID: "createSubmissionAuditComment", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, CreateSubmissionAuditCommentOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + 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 { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeCreateSubmissionAuditCommentParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + request, close, err := s.decodeCreateSubmissionAuditCommentRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CreateSubmissionAuditCommentNoContent + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateSubmissionAuditCommentOperation, + OperationSummary: "Post a comment to the audit log", + OperationID: "createSubmissionAuditComment", + Body: request, + Params: middleware.Parameters{ + { + Name: "SubmissionID", + In: "path", + }: params.SubmissionID, + }, + Raw: r, + } + + type ( + Request = CreateSubmissionAuditCommentReq + Params = CreateSubmissionAuditCommentParams + Response = *CreateSubmissionAuditCommentNoContent + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackCreateSubmissionAuditCommentParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.CreateSubmissionAuditComment(ctx, request, params) + return response, err + }, + ) + } else { + err = s.h.CreateSubmissionAuditComment(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateSubmissionAuditCommentResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleDeleteScriptRequest handles deleteScript operation. // // Delete the specified script by ID. @@ -5650,6 +6070,163 @@ func (s *Server) handleGetSubmissionRequest(args [1]string, argsEscaped bool, w } } +// handleListMapfixAuditEventsRequest handles listMapfixAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /mapfixes/{MapfixID}/audit-events +func (s *Server) handleListMapfixAuditEventsRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("listMapfixAuditEvents"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/audit-events"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListMapfixAuditEventsOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListMapfixAuditEventsOperation, + ID: "listMapfixAuditEvents", + } + ) + params, err := decodeListMapfixAuditEventsParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response []AuditEvent + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListMapfixAuditEventsOperation, + OperationSummary: "Retrieve a list of audit events", + OperationID: "listMapfixAuditEvents", + Body: nil, + Params: middleware.Parameters{ + { + Name: "MapfixID", + In: "path", + }: params.MapfixID, + { + Name: "Page", + In: "query", + }: params.Page, + { + Name: "Limit", + In: "query", + }: params.Limit, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = ListMapfixAuditEventsParams + Response = []AuditEvent + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackListMapfixAuditEventsParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListMapfixAuditEvents(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.ListMapfixAuditEvents(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListMapfixAuditEventsResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleListMapfixesRequest handles listMapfixes operation. // // Get list of mapfixes. @@ -6342,6 +6919,163 @@ func (s *Server) handleListScriptsRequest(args [0]string, argsEscaped bool, w ht } } +// handleListSubmissionAuditEventsRequest handles listSubmissionAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /submissions/{SubmissionID}/audit-events +func (s *Server) handleListSubmissionAuditEventsRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("listSubmissionAuditEvents"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/audit-events"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListSubmissionAuditEventsOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListSubmissionAuditEventsOperation, + ID: "listSubmissionAuditEvents", + } + ) + params, err := decodeListSubmissionAuditEventsParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response []AuditEvent + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListSubmissionAuditEventsOperation, + OperationSummary: "Retrieve a list of audit events", + OperationID: "listSubmissionAuditEvents", + Body: nil, + Params: middleware.Parameters{ + { + Name: "SubmissionID", + In: "path", + }: params.SubmissionID, + { + Name: "Page", + In: "query", + }: params.Page, + { + Name: "Limit", + In: "query", + }: params.Limit, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = ListSubmissionAuditEventsParams + Response = []AuditEvent + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackListSubmissionAuditEventsParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListSubmissionAuditEvents(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.ListSubmissionAuditEvents(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListSubmissionAuditEventsResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleListSubmissionsRequest handles listSubmissions operation. // // Get list of submissions. diff --git a/pkg/api/oas_json_gen.go b/pkg/api/oas_json_gen.go index 391642f..6d63001 100644 --- a/pkg/api/oas_json_gen.go +++ b/pkg/api/oas_json_gen.go @@ -13,6 +13,260 @@ import ( "github.com/ogen-go/ogen/validate" ) +// Encode implements json.Marshaler. +func (s *AuditEvent) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuditEvent) encodeFields(e *jx.Encoder) { + { + e.FieldStart("ID") + e.Int64(s.ID) + } + { + e.FieldStart("Date") + e.Int64(s.Date) + } + { + e.FieldStart("User") + e.Int64(s.User) + } + { + e.FieldStart("ResourceType") + e.Int32(s.ResourceType) + } + { + e.FieldStart("ResourceID") + e.Int64(s.ResourceID) + } + { + e.FieldStart("EventType") + e.Int32(s.EventType) + } + { + e.FieldStart("EventData") + s.EventData.Encode(e) + } +} + +var jsonFieldsNameOfAuditEvent = [7]string{ + 0: "ID", + 1: "Date", + 2: "User", + 3: "ResourceType", + 4: "ResourceID", + 5: "EventType", + 6: "EventData", +} + +// Decode decodes AuditEvent from json. +func (s *AuditEvent) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuditEvent to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "ID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ID\"") + } + case "Date": + requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Int64() + s.Date = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Date\"") + } + case "User": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Int64() + s.User = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"User\"") + } + case "ResourceType": + requiredBitSet[0] |= 1 << 3 + if err := func() error { + v, err := d.Int32() + s.ResourceType = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ResourceType\"") + } + case "ResourceID": + requiredBitSet[0] |= 1 << 4 + if err := func() error { + v, err := d.Int64() + s.ResourceID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ResourceID\"") + } + case "EventType": + requiredBitSet[0] |= 1 << 5 + if err := func() error { + v, err := d.Int32() + s.EventType = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"EventType\"") + } + case "EventData": + requiredBitSet[0] |= 1 << 6 + if err := func() error { + if err := s.EventData.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"EventData\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode AuditEvent") + } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b01111111, + } { + if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { + // Mask only required fields and check equality to mask using XOR. + // + // If XOR result is not zero, result is not equal to expected, so some fields are missed. + // Bits of fields which would be set are actually bits of missed fields. + missed := bits.OnesCount8(result) + for bitN := 0; bitN < missed; bitN++ { + bitIdx := bits.TrailingZeros8(result) + fieldIdx := i*8 + bitIdx + var name string + if fieldIdx < len(jsonFieldsNameOfAuditEvent) { + name = jsonFieldsNameOfAuditEvent[fieldIdx] + } else { + name = strconv.Itoa(fieldIdx) + } + failures = append(failures, validate.FieldError{ + Name: name, + Error: validate.ErrFieldRequired, + }) + // Reset bit. + result &^= 1 << bitIdx + } + } + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuditEvent) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuditEvent) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s AuditEventEventData) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields implements json.Marshaler. +func (s AuditEventEventData) encodeFields(e *jx.Encoder) { + for k, elem := range s { + e.FieldStart(k) + + if len(elem) != 0 { + e.Raw(elem) + } + } +} + +// Decode decodes AuditEventEventData from json. +func (s *AuditEventEventData) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuditEventEventData to nil") + } + m := s.init() + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + var elem jx.Raw + if err := func() error { + v, err := d.RawAppend(nil) + elem = jx.Raw(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrapf(err, "decode field %q", k) + } + m[string(k)] = elem + return nil + }); err != nil { + return errors.Wrap(err, "decode AuditEventEventData") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s AuditEventEventData) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuditEventEventData) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode implements json.Marshaler. func (s *Error) Encode(e *jx.Encoder) { e.ObjStart() diff --git a/pkg/api/oas_operations_gen.go b/pkg/api/oas_operations_gen.go index 9806eb1..09d06f4 100644 --- a/pkg/api/oas_operations_gen.go +++ b/pkg/api/oas_operations_gen.go @@ -25,9 +25,11 @@ const ( ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate" ActionSubmissionValidatedOperation OperationName = "ActionSubmissionValidated" CreateMapfixOperation OperationName = "CreateMapfix" + CreateMapfixAuditCommentOperation OperationName = "CreateMapfixAuditComment" CreateScriptOperation OperationName = "CreateScript" CreateScriptPolicyOperation OperationName = "CreateScriptPolicy" CreateSubmissionOperation OperationName = "CreateSubmission" + CreateSubmissionAuditCommentOperation OperationName = "CreateSubmissionAuditComment" DeleteScriptOperation OperationName = "DeleteScript" DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy" GetMapOperation OperationName = "GetMap" @@ -36,10 +38,12 @@ const ( GetScriptOperation OperationName = "GetScript" GetScriptPolicyOperation OperationName = "GetScriptPolicy" GetSubmissionOperation OperationName = "GetSubmission" + ListMapfixAuditEventsOperation OperationName = "ListMapfixAuditEvents" ListMapfixesOperation OperationName = "ListMapfixes" ListMapsOperation OperationName = "ListMaps" ListScriptPolicyOperation OperationName = "ListScriptPolicy" ListScriptsOperation OperationName = "ListScripts" + ListSubmissionAuditEventsOperation OperationName = "ListSubmissionAuditEvents" ListSubmissionsOperation OperationName = "ListSubmissions" ReleaseSubmissionsOperation OperationName = "ReleaseSubmissions" SessionRolesOperation OperationName = "SessionRoles" diff --git a/pkg/api/oas_parameters_gen.go b/pkg/api/oas_parameters_gen.go index 157e1e3..b604dc9 100644 --- a/pkg/api/oas_parameters_gen.go +++ b/pkg/api/oas_parameters_gen.go @@ -1509,6 +1509,172 @@ func decodeActionSubmissionValidatedParams(args [1]string, argsEscaped bool, r * return params, nil } +// CreateMapfixAuditCommentParams is parameters of createMapfixAuditComment operation. +type CreateMapfixAuditCommentParams struct { + // The unique identifier for a mapfix. + MapfixID int64 +} + +func unpackCreateMapfixAuditCommentParams(packed middleware.Parameters) (params CreateMapfixAuditCommentParams) { + { + key := middleware.ParameterKey{ + Name: "MapfixID", + In: "path", + } + params.MapfixID = packed[key].(int64) + } + return params +} + +func decodeCreateMapfixAuditCommentParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateMapfixAuditCommentParams, _ error) { + // Decode path: MapfixID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "MapfixID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.MapfixID = c + return nil + }(); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: false, + Max: 0, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.MapfixID)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "MapfixID", + In: "path", + Err: err, + } + } + return params, nil +} + +// CreateSubmissionAuditCommentParams is parameters of createSubmissionAuditComment operation. +type CreateSubmissionAuditCommentParams struct { + // The unique identifier for a submission. + SubmissionID int64 +} + +func unpackCreateSubmissionAuditCommentParams(packed middleware.Parameters) (params CreateSubmissionAuditCommentParams) { + { + key := middleware.ParameterKey{ + Name: "SubmissionID", + In: "path", + } + params.SubmissionID = packed[key].(int64) + } + return params +} + +func decodeCreateSubmissionAuditCommentParams(args [1]string, argsEscaped bool, r *http.Request) (params CreateSubmissionAuditCommentParams, _ error) { + // Decode path: SubmissionID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "SubmissionID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.SubmissionID = c + return nil + }(); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: false, + Max: 0, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.SubmissionID)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "SubmissionID", + In: "path", + Err: err, + } + } + return params, nil +} + // DeleteScriptParams is parameters of deleteScript operation. type DeleteScriptParams struct { // The unique identifier for a script. @@ -2173,6 +2339,212 @@ func decodeGetSubmissionParams(args [1]string, argsEscaped bool, r *http.Request return params, nil } +// ListMapfixAuditEventsParams is parameters of listMapfixAuditEvents operation. +type ListMapfixAuditEventsParams struct { + // The unique identifier for a mapfix. + MapfixID int64 + Page int32 + Limit int32 +} + +func unpackListMapfixAuditEventsParams(packed middleware.Parameters) (params ListMapfixAuditEventsParams) { + { + key := middleware.ParameterKey{ + Name: "MapfixID", + In: "path", + } + params.MapfixID = packed[key].(int64) + } + { + key := middleware.ParameterKey{ + Name: "Page", + In: "query", + } + params.Page = packed[key].(int32) + } + { + key := middleware.ParameterKey{ + Name: "Limit", + In: "query", + } + params.Limit = packed[key].(int32) + } + return params +} + +func decodeListMapfixAuditEventsParams(args [1]string, argsEscaped bool, r *http.Request) (params ListMapfixAuditEventsParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode path: MapfixID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "MapfixID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.MapfixID = c + return nil + }(); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: false, + Max: 0, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.MapfixID)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "MapfixID", + In: "path", + Err: err, + } + } + // Decode query: Page. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "Page", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt32(val) + if err != nil { + return err + } + + params.Page = c + return nil + }); err != nil { + return err + } + 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(params.Page)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return err + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "Page", + In: "query", + Err: err, + } + } + // Decode query: Limit. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "Limit", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt32(val) + if err != nil { + return err + } + + params.Limit = c + return nil + }); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: true, + Max: 100, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.Limit)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return err + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "Limit", + In: "query", + Err: err, + } + } + return params, nil +} + // ListMapfixesParams is parameters of listMapfixes operation. type ListMapfixesParams struct { Page int32 @@ -2360,7 +2732,7 @@ func decodeListMapfixesParams(args [0]string, argsEscaped bool, r *http.Request) if err := func() error { if err := (validate.Int{ MinSet: true, - Min: 1, + Min: 0, MaxSet: true, Max: 100, MinExclusive: false, @@ -3053,7 +3425,7 @@ func decodeListMapsParams(args [0]string, argsEscaped bool, r *http.Request) (pa if err := func() error { if err := (validate.Int{ MinSet: true, - Min: 1, + Min: 0, MaxSet: true, Max: 100, MinExclusive: false, @@ -3476,7 +3848,7 @@ func decodeListScriptPolicyParams(args [0]string, argsEscaped bool, r *http.Requ if err := func() error { if err := (validate.Int{ MinSet: true, - Min: 1, + Min: 0, MaxSet: true, Max: 100, MinExclusive: false, @@ -3855,7 +4227,7 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request) if err := func() error { if err := (validate.Int{ MinSet: true, - Min: 1, + Min: 0, MaxSet: true, Max: 100, MinExclusive: false, @@ -4205,6 +4577,212 @@ func decodeListScriptsParams(args [0]string, argsEscaped bool, r *http.Request) return params, nil } +// ListSubmissionAuditEventsParams is parameters of listSubmissionAuditEvents operation. +type ListSubmissionAuditEventsParams struct { + // The unique identifier for a submission. + SubmissionID int64 + Page int32 + Limit int32 +} + +func unpackListSubmissionAuditEventsParams(packed middleware.Parameters) (params ListSubmissionAuditEventsParams) { + { + key := middleware.ParameterKey{ + Name: "SubmissionID", + In: "path", + } + params.SubmissionID = packed[key].(int64) + } + { + key := middleware.ParameterKey{ + Name: "Page", + In: "query", + } + params.Page = packed[key].(int32) + } + { + key := middleware.ParameterKey{ + Name: "Limit", + In: "query", + } + params.Limit = packed[key].(int32) + } + return params +} + +func decodeListSubmissionAuditEventsParams(args [1]string, argsEscaped bool, r *http.Request) (params ListSubmissionAuditEventsParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode path: SubmissionID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "SubmissionID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.SubmissionID = c + return nil + }(); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: false, + Max: 0, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.SubmissionID)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "SubmissionID", + In: "path", + Err: err, + } + } + // Decode query: Page. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "Page", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt32(val) + if err != nil { + return err + } + + params.Page = c + return nil + }); err != nil { + return err + } + 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(params.Page)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return err + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "Page", + In: "query", + Err: err, + } + } + // Decode query: Limit. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "Limit", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt32(val) + if err != nil { + return err + } + + params.Limit = c + return nil + }); err != nil { + return err + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: true, + Max: 100, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(params.Limit)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + return err + } + } else { + return err + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "Limit", + In: "query", + Err: err, + } + } + return params, nil +} + // ListSubmissionsParams is parameters of listSubmissions operation. type ListSubmissionsParams struct { Page int32 @@ -4392,7 +4970,7 @@ func decodeListSubmissionsParams(args [0]string, argsEscaped bool, r *http.Reque if err := func() error { if err := (validate.Int{ MinSet: true, - Min: 1, + Min: 0, MaxSet: true, Max: 100, MinExclusive: false, diff --git a/pkg/api/oas_request_decoders_gen.go b/pkg/api/oas_request_decoders_gen.go index a105ace..72c4ed7 100644 --- a/pkg/api/oas_request_decoders_gen.go +++ b/pkg/api/oas_request_decoders_gen.go @@ -87,6 +87,40 @@ func (s *Server) decodeCreateMapfixRequest(r *http.Request) ( } } +func (s *Server) decodeCreateMapfixAuditCommentRequest(r *http.Request) ( + req CreateMapfixAuditCommentReq, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = 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 == "text/plain": + reader := r.Body + request := CreateMapfixAuditCommentReq{Data: reader} + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + func (s *Server) decodeCreateScriptRequest(r *http.Request) ( req *ScriptCreate, close func() error, @@ -300,6 +334,40 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) ( } } +func (s *Server) decodeCreateSubmissionAuditCommentRequest(r *http.Request) ( + req CreateSubmissionAuditCommentReq, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = 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 == "text/plain": + reader := r.Body + request := CreateSubmissionAuditCommentReq{Data: reader} + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + func (s *Server) decodeReleaseSubmissionsRequest(r *http.Request) ( req []ReleaseInfo, close func() error, diff --git a/pkg/api/oas_request_encoders_gen.go b/pkg/api/oas_request_encoders_gen.go index 52f1046..84923a2 100644 --- a/pkg/api/oas_request_encoders_gen.go +++ b/pkg/api/oas_request_encoders_gen.go @@ -25,6 +25,16 @@ func encodeCreateMapfixRequest( return nil } +func encodeCreateMapfixAuditCommentRequest( + req CreateMapfixAuditCommentReq, + r *http.Request, +) error { + const contentType = "text/plain" + body := req + ht.SetBody(r, body, contentType) + return nil +} + func encodeCreateScriptRequest( req *ScriptCreate, r *http.Request, @@ -67,6 +77,16 @@ func encodeCreateSubmissionRequest( return nil } +func encodeCreateSubmissionAuditCommentRequest( + req CreateSubmissionAuditCommentReq, + r *http.Request, +) error { + const contentType = "text/plain" + body := req + ht.SetBody(r, body, contentType) + return nil +} + func encodeReleaseSubmissionsRequest( req []ReleaseInfo, r *http.Request, diff --git a/pkg/api/oas_response_decoders_gen.go b/pkg/api/oas_response_decoders_gen.go index b23ae6c..242b3b7 100644 --- a/pkg/api/oas_response_decoders_gen.go +++ b/pkg/api/oas_response_decoders_gen.go @@ -1196,6 +1196,66 @@ func decodeCreateMapfixResponse(resp *http.Response) (res *OperationID, _ error) return res, errors.Wrap(defRes, "error") } +func decodeCreateMapfixAuditCommentResponse(resp *http.Response) (res *CreateMapfixAuditCommentNoContent, _ error) { + switch resp.StatusCode { + case 204: + // Code 204. + return &CreateMapfixAuditCommentNoContent{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeCreateScriptResponse(resp *http.Response) (res *ScriptID, _ error) { switch resp.StatusCode { case 201: @@ -1499,6 +1559,66 @@ func decodeCreateSubmissionResponse(resp *http.Response) (res *OperationID, _ er return res, errors.Wrap(defRes, "error") } +func decodeCreateSubmissionAuditCommentResponse(resp *http.Response) (res *CreateSubmissionAuditCommentNoContent, _ error) { + switch resp.StatusCode { + case 204: + // Code 204. + return &CreateSubmissionAuditCommentNoContent{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeDeleteScriptResponse(resp *http.Response) (res *DeleteScriptNoContent, _ error) { switch resp.StatusCode { case 204: @@ -2225,6 +2345,115 @@ func decodeGetSubmissionResponse(resp *http.Response) (res *Submission, _ error) return res, errors.Wrap(defRes, "error") } +func decodeListMapfixAuditEventsResponse(resp *http.Response) (res []AuditEvent, _ 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 []AuditEvent + if err := func() error { + response = make([]AuditEvent, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem AuditEvent + 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") + } + 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 + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeListMapfixesResponse(resp *http.Response) (res *Mapfixes, _ error) { switch resp.StatusCode { case 200: @@ -2704,6 +2933,115 @@ func decodeListScriptsResponse(resp *http.Response) (res []Script, _ error) { return res, errors.Wrap(defRes, "error") } +func decodeListSubmissionAuditEventsResponse(resp *http.Response) (res []AuditEvent, _ 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 []AuditEvent + if err := func() error { + response = make([]AuditEvent, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem AuditEvent + 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") + } + 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 + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeListSubmissionsResponse(resp *http.Response) (res *Submissions, _ error) { switch resp.StatusCode { case 200: diff --git a/pkg/api/oas_response_encoders_gen.go b/pkg/api/oas_response_encoders_gen.go index 362dfc5..cb0a98a 100644 --- a/pkg/api/oas_response_encoders_gen.go +++ b/pkg/api/oas_response_encoders_gen.go @@ -153,6 +153,13 @@ func encodeCreateMapfixResponse(response *OperationID, w http.ResponseWriter, sp return nil } +func encodeCreateMapfixAuditCommentResponse(response *CreateMapfixAuditCommentNoContent, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(204) + span.SetStatus(codes.Ok, http.StatusText(204)) + + return nil +} + func encodeCreateScriptResponse(response *ScriptID, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(201) @@ -195,6 +202,13 @@ func encodeCreateSubmissionResponse(response *OperationID, w http.ResponseWriter return nil } +func encodeCreateSubmissionAuditCommentResponse(response *CreateSubmissionAuditCommentNoContent, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(204) + span.SetStatus(codes.Ok, http.StatusText(204)) + + return nil +} + func encodeDeleteScriptResponse(response *DeleteScriptNoContent, w http.ResponseWriter, span trace.Span) error { w.WriteHeader(204) span.SetStatus(codes.Ok, http.StatusText(204)) @@ -293,6 +307,24 @@ func encodeGetSubmissionResponse(response *Submission, w http.ResponseWriter, sp return nil } +func encodeListMapfixAuditEventsResponse(response []AuditEvent, 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 encodeListMapfixesResponse(response *Mapfixes, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) @@ -361,6 +393,24 @@ func encodeListScriptsResponse(response []Script, w http.ResponseWriter, span tr return nil } +func encodeListSubmissionAuditEventsResponse(response []AuditEvent, 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 *Submissions, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) diff --git a/pkg/api/oas_router_gen.go b/pkg/api/oas_router_gen.go index 414d7e4..6989865 100644 --- a/pkg/api/oas_router_gen.go +++ b/pkg/api/oas_router_gen.go @@ -136,9 +136,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case 'c': // Prefix: "completed" + case 'a': // Prefix: "audit-events" - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { + if l := len("audit-events"); len(elem) >= l && elem[0:l] == "audit-events" { elem = elem[l:] } else { break @@ -147,17 +147,75 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { if len(elem) == 0 { // Leaf node. switch r.Method { - case "POST": - s.handleSetMapfixCompletedRequest([1]string{ + case "GET": + s.handleListMapfixAuditEventsRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: - s.notAllowed(w, r, "POST") + s.notAllowed(w, r, "GET") } return } + case 'c': // Prefix: "com" + + if l := len("com"); len(elem) >= l && elem[0:l] == "com" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'm': // Prefix: "ment" + + if l := len("ment"); len(elem) >= l && elem[0:l] == "ment" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleCreateMapfixAuditCommentRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + + case 'p': // Prefix: "pleted" + + if l := len("pleted"); len(elem) >= l && elem[0:l] == "pleted" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleSetMapfixCompletedRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + + } + case 'm': // Prefix: "model" if l := len("model"); len(elem) >= l && elem[0:l] == "model" { @@ -832,9 +890,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case 'c': // Prefix: "completed" + case 'a': // Prefix: "audit-events" - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { + if l := len("audit-events"); len(elem) >= l && elem[0:l] == "audit-events" { elem = elem[l:] } else { break @@ -843,17 +901,75 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { if len(elem) == 0 { // Leaf node. switch r.Method { - case "POST": - s.handleSetSubmissionCompletedRequest([1]string{ + case "GET": + s.handleListSubmissionAuditEventsRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: - s.notAllowed(w, r, "POST") + s.notAllowed(w, r, "GET") } return } + case 'c': // Prefix: "com" + + if l := len("com"); len(elem) >= l && elem[0:l] == "com" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'm': // Prefix: "ment" + + if l := len("ment"); len(elem) >= l && elem[0:l] == "ment" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleCreateSubmissionAuditCommentRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + + case 'p': // Prefix: "pleted" + + if l := len("pleted"); len(elem) >= l && elem[0:l] == "pleted" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleSetSubmissionCompletedRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + + } + case 'm': // Prefix: "model" if l := len("model"); len(elem) >= l && elem[0:l] == "model" { @@ -1319,9 +1435,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case 'c': // Prefix: "completed" + case 'a': // Prefix: "audit-events" - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { + if l := len("audit-events"); len(elem) >= l && elem[0:l] == "audit-events" { elem = elem[l:] } else { break @@ -1330,11 +1446,11 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { if len(elem) == 0 { // Leaf node. switch method { - case "POST": - r.name = SetMapfixCompletedOperation - r.summary = "Called by maptest when a player completes the map" - r.operationID = "setMapfixCompleted" - r.pathPattern = "/mapfixes/{MapfixID}/completed" + case "GET": + r.name = ListMapfixAuditEventsOperation + r.summary = "Retrieve a list of audit events" + r.operationID = "listMapfixAuditEvents" + r.pathPattern = "/mapfixes/{MapfixID}/audit-events" r.args = args r.count = 1 return r, true @@ -1343,6 +1459,68 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } } + case 'c': // Prefix: "com" + + if l := len("com"); len(elem) >= l && elem[0:l] == "com" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'm': // Prefix: "ment" + + if l := len("ment"); len(elem) >= l && elem[0:l] == "ment" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = CreateMapfixAuditCommentOperation + r.summary = "Post a comment to the audit log" + r.operationID = "createMapfixAuditComment" + r.pathPattern = "/mapfixes/{MapfixID}/comment" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + case 'p': // Prefix: "pleted" + + if l := len("pleted"); len(elem) >= l && elem[0:l] == "pleted" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = SetMapfixCompletedOperation + r.summary = "Called by maptest when a player completes the map" + r.operationID = "setMapfixCompleted" + r.pathPattern = "/mapfixes/{MapfixID}/completed" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + } + case 'm': // Prefix: "model" if l := len("model"); len(elem) >= l && elem[0:l] == "model" { @@ -2113,9 +2291,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case 'c': // Prefix: "completed" + case 'a': // Prefix: "audit-events" - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { + if l := len("audit-events"); len(elem) >= l && elem[0:l] == "audit-events" { elem = elem[l:] } else { break @@ -2124,11 +2302,11 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { if len(elem) == 0 { // Leaf node. switch method { - case "POST": - r.name = SetSubmissionCompletedOperation - r.summary = "Called by maptest when a player completes the map" - r.operationID = "setSubmissionCompleted" - r.pathPattern = "/submissions/{SubmissionID}/completed" + case "GET": + r.name = ListSubmissionAuditEventsOperation + r.summary = "Retrieve a list of audit events" + r.operationID = "listSubmissionAuditEvents" + r.pathPattern = "/submissions/{SubmissionID}/audit-events" r.args = args r.count = 1 return r, true @@ -2137,6 +2315,68 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } } + case 'c': // Prefix: "com" + + if l := len("com"); len(elem) >= l && elem[0:l] == "com" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'm': // Prefix: "ment" + + if l := len("ment"); len(elem) >= l && elem[0:l] == "ment" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = CreateSubmissionAuditCommentOperation + r.summary = "Post a comment to the audit log" + r.operationID = "createSubmissionAuditComment" + r.pathPattern = "/submissions/{SubmissionID}/comment" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + case 'p': // Prefix: "pleted" + + if l := len("pleted"); len(elem) >= l && elem[0:l] == "pleted" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = SetSubmissionCompletedOperation + r.summary = "Called by maptest when a player completes the map" + r.operationID = "setSubmissionCompleted" + r.pathPattern = "/submissions/{SubmissionID}/completed" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + } + case 'm': // Prefix: "model" if l := len("model"); len(elem) >= l && elem[0:l] == "model" { diff --git a/pkg/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go index 80ee714..5590292 100644 --- a/pkg/api/oas_schemas_gen.go +++ b/pkg/api/oas_schemas_gen.go @@ -4,7 +4,10 @@ package api import ( "fmt" + "io" "time" + + "github.com/go-faster/jx" ) func (s *ErrorStatusCode) Error() string { @@ -65,6 +68,101 @@ type ActionSubmissionTriggerValidateNoContent struct{} // ActionSubmissionValidatedNoContent is response for ActionSubmissionValidated operation. type ActionSubmissionValidatedNoContent struct{} +// Ref: #/components/schemas/AuditEvent +type AuditEvent struct { + ID int64 `json:"ID"` + Date int64 `json:"Date"` + User int64 `json:"User"` + // Is this a submission or is it a mapfix. + ResourceType int32 `json:"ResourceType"` + ResourceID int64 `json:"ResourceID"` + EventType int32 `json:"EventType"` + // Arbitrary event data. + EventData AuditEventEventData `json:"EventData"` +} + +// GetID returns the value of ID. +func (s *AuditEvent) GetID() int64 { + return s.ID +} + +// GetDate returns the value of Date. +func (s *AuditEvent) GetDate() int64 { + return s.Date +} + +// GetUser returns the value of User. +func (s *AuditEvent) GetUser() int64 { + return s.User +} + +// GetResourceType returns the value of ResourceType. +func (s *AuditEvent) GetResourceType() int32 { + return s.ResourceType +} + +// GetResourceID returns the value of ResourceID. +func (s *AuditEvent) GetResourceID() int64 { + return s.ResourceID +} + +// GetEventType returns the value of EventType. +func (s *AuditEvent) GetEventType() int32 { + return s.EventType +} + +// GetEventData returns the value of EventData. +func (s *AuditEvent) GetEventData() AuditEventEventData { + return s.EventData +} + +// SetID sets the value of ID. +func (s *AuditEvent) SetID(val int64) { + s.ID = val +} + +// SetDate sets the value of Date. +func (s *AuditEvent) SetDate(val int64) { + s.Date = val +} + +// SetUser sets the value of User. +func (s *AuditEvent) SetUser(val int64) { + s.User = val +} + +// SetResourceType sets the value of ResourceType. +func (s *AuditEvent) SetResourceType(val int32) { + s.ResourceType = val +} + +// SetResourceID sets the value of ResourceID. +func (s *AuditEvent) SetResourceID(val int64) { + s.ResourceID = val +} + +// SetEventType sets the value of EventType. +func (s *AuditEvent) SetEventType(val int32) { + s.EventType = val +} + +// SetEventData sets the value of EventData. +func (s *AuditEvent) SetEventData(val AuditEventEventData) { + s.EventData = val +} + +// Arbitrary event data. +type AuditEventEventData map[string]jx.Raw + +func (s *AuditEventEventData) init() AuditEventEventData { + m := *s + if m == nil { + m = map[string]jx.Raw{} + *s = m + } + return m +} + type CookieAuth struct { APIKey string } @@ -79,6 +177,40 @@ func (s *CookieAuth) SetAPIKey(val string) { s.APIKey = val } +// CreateMapfixAuditCommentNoContent is response for CreateMapfixAuditComment operation. +type CreateMapfixAuditCommentNoContent struct{} + +type CreateMapfixAuditCommentReq struct { + Data io.Reader +} + +// Read reads data from the Data reader. +// +// Kept to satisfy the io.Reader interface. +func (s CreateMapfixAuditCommentReq) Read(p []byte) (n int, err error) { + if s.Data == nil { + return 0, io.EOF + } + return s.Data.Read(p) +} + +// CreateSubmissionAuditCommentNoContent is response for CreateSubmissionAuditComment operation. +type CreateSubmissionAuditCommentNoContent struct{} + +type CreateSubmissionAuditCommentReq struct { + Data io.Reader +} + +// Read reads data from the Data reader. +// +// Kept to satisfy the io.Reader interface. +func (s CreateSubmissionAuditCommentReq) Read(p []byte) (n int, err error) { + if s.Data == nil { + return 0, io.EOF + } + return s.Data.Read(p) +} + // DeleteScriptNoContent is response for DeleteScript operation. type DeleteScriptNoContent struct{} diff --git a/pkg/api/oas_server_gen.go b/pkg/api/oas_server_gen.go index 99b8e44..0fddb0c 100644 --- a/pkg/api/oas_server_gen.go +++ b/pkg/api/oas_server_gen.go @@ -122,6 +122,12 @@ type Handler interface { // // POST /mapfixes CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (*OperationID, error) + // CreateMapfixAuditComment implements createMapfixAuditComment operation. + // + // Post a comment to the audit log. + // + // POST /mapfixes/{MapfixID}/comment + CreateMapfixAuditComment(ctx context.Context, req CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error // CreateScript implements createScript operation. // // Create a new script. @@ -140,6 +146,12 @@ type Handler interface { // // POST /submissions CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (*OperationID, error) + // CreateSubmissionAuditComment implements createSubmissionAuditComment operation. + // + // Post a comment to the audit log. + // + // POST /submissions/{SubmissionID}/comment + CreateSubmissionAuditComment(ctx context.Context, req CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error // DeleteScript implements deleteScript operation. // // Delete the specified script by ID. @@ -188,6 +200,12 @@ type Handler interface { // // GET /submissions/{SubmissionID} GetSubmission(ctx context.Context, params GetSubmissionParams) (*Submission, error) + // ListMapfixAuditEvents implements listMapfixAuditEvents operation. + // + // Retrieve a list of audit events. + // + // GET /mapfixes/{MapfixID}/audit-events + ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) ([]AuditEvent, error) // ListMapfixes implements listMapfixes operation. // // Get list of mapfixes. @@ -212,6 +230,12 @@ type Handler interface { // // GET /scripts ListScripts(ctx context.Context, params ListScriptsParams) ([]Script, error) + // ListSubmissionAuditEvents implements listSubmissionAuditEvents operation. + // + // Retrieve a list of audit events. + // + // GET /submissions/{SubmissionID}/audit-events + ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) ([]AuditEvent, error) // ListSubmissions implements listSubmissions operation. // // Get list of submissions. diff --git a/pkg/api/oas_unimplemented_gen.go b/pkg/api/oas_unimplemented_gen.go index 56392ad..cacd62c 100644 --- a/pkg/api/oas_unimplemented_gen.go +++ b/pkg/api/oas_unimplemented_gen.go @@ -184,6 +184,15 @@ func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixTrigger return r, ht.ErrNotImplemented } +// CreateMapfixAuditComment implements createMapfixAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /mapfixes/{MapfixID}/comment +func (UnimplementedHandler) CreateMapfixAuditComment(ctx context.Context, req CreateMapfixAuditCommentReq, params CreateMapfixAuditCommentParams) error { + return ht.ErrNotImplemented +} + // CreateScript implements createScript operation. // // Create a new script. @@ -211,6 +220,15 @@ func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *Submissio return r, ht.ErrNotImplemented } +// CreateSubmissionAuditComment implements createSubmissionAuditComment operation. +// +// Post a comment to the audit log. +// +// POST /submissions/{SubmissionID}/comment +func (UnimplementedHandler) CreateSubmissionAuditComment(ctx context.Context, req CreateSubmissionAuditCommentReq, params CreateSubmissionAuditCommentParams) error { + return ht.ErrNotImplemented +} + // DeleteScript implements deleteScript operation. // // Delete the specified script by ID. @@ -283,6 +301,15 @@ func (UnimplementedHandler) GetSubmission(ctx context.Context, params GetSubmiss return r, ht.ErrNotImplemented } +// ListMapfixAuditEvents implements listMapfixAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /mapfixes/{MapfixID}/audit-events +func (UnimplementedHandler) ListMapfixAuditEvents(ctx context.Context, params ListMapfixAuditEventsParams) (r []AuditEvent, _ error) { + return r, ht.ErrNotImplemented +} + // ListMapfixes implements listMapfixes operation. // // Get list of mapfixes. @@ -319,6 +346,15 @@ func (UnimplementedHandler) ListScripts(ctx context.Context, params ListScriptsP return r, ht.ErrNotImplemented } +// ListSubmissionAuditEvents implements listSubmissionAuditEvents operation. +// +// Retrieve a list of audit events. +// +// GET /submissions/{SubmissionID}/audit-events +func (UnimplementedHandler) ListSubmissionAuditEvents(ctx context.Context, params ListSubmissionAuditEventsParams) (r []AuditEvent, _ error) { + return r, ht.ErrNotImplemented +} + // ListSubmissions implements listSubmissions operation. // // Get list of submissions.