diff --git a/changelog/18465.txt b/changelog/18465.txt new file mode 100644 index 000000000000..928da99bc4fe --- /dev/null +++ b/changelog/18465.txt @@ -0,0 +1,3 @@ +```release-note:improvement +openapi: add openapi response defintions to /sys/auth endpoints +``` \ No newline at end of file diff --git a/vault/logical_system_paths.go b/vault/logical_system_paths.go index 26c3e5aa0b20..648c8d82c6f4 100644 --- a/vault/logical_system_paths.go +++ b/vault/logical_system_paths.go @@ -1569,8 +1569,17 @@ func (b *SystemBackend) authPaths() []*framework.Path { return []*framework.Path{ { Pattern: "auth$", - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.ReadOperation: b.handleAuthTable, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.ReadOperation: &framework.PathOperation{ + Callback: b.handleAuthTable, + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + // response keys are dynamic + Fields: nil, + }}, + }, + }, }, HelpSynopsis: strings.TrimSpace(sysHelp["auth-table"][0]), HelpDescription: strings.TrimSpace(sysHelp["auth-table"][1]), @@ -1636,11 +1645,95 @@ func (b *SystemBackend) authPaths() []*framework.Path { Callback: b.handleAuthTuneRead, Summary: "Reads the given auth path's configuration.", Description: "This endpoint requires sudo capability on the final path, but the same functionality can be achieved without sudo via `sys/mounts/auth/[auth-path]/tune`.", + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + Fields: map[string]*framework.FieldSchema{ + "description": { + Type: framework.TypeString, + Required: true, + }, + "default_lease_ttl": { + Type: framework.TypeInt, + Required: true, + }, + "max_lease_ttl": { + Type: framework.TypeInt, + Required: true, + }, + "force_no_cache": { + Type: framework.TypeBool, + Required: true, + }, + "external_entropy_access": { + Type: framework.TypeBool, + Required: false, + }, + "token_type": { + Type: framework.TypeString, + Required: false, + }, + "audit_non_hmac_request_keys": { + Type: framework.TypeCommaStringSlice, + Required: false, + }, + "audit_non_hmac_response_keys": { + Type: framework.TypeCommaStringSlice, + Required: false, + }, + "listing_visibility": { + Type: framework.TypeString, + Required: false, + }, + "passthrough_request_headers": { + Type: framework.TypeCommaStringSlice, + Required: false, + }, + "allowed_response_headers": { + Type: framework.TypeCommaStringSlice, + Required: false, + }, + "allowed_managed_keys": { + Type: framework.TypeCommaStringSlice, + Required: false, + }, + "user_lockout_counter_reset_duration": { + Type: framework.TypeInt64, + Required: false, + }, + "user_lockout_threshold": { + Type: framework.TypeInt64, // uint64 + Required: false, + }, + "user_lockout_duration": { + Type: framework.TypeInt64, + Required: false, + }, + "user_lockout_disable": { + Type: framework.TypeBool, + Required: false, + }, + "options": { + Type: framework.TypeMap, + Required: false, + }, + "plugin_version": { + Type: framework.TypeString, + Required: false, + }, + }, + }}, + }, }, logical.UpdateOperation: &framework.PathOperation{ Callback: b.handleAuthTuneWrite, Summary: "Tune configuration parameters for a given auth path.", Description: "This endpoint requires sudo capability on the final path, but the same functionality can be achieved without sudo via `sys/mounts/auth/[auth-path]/tune`.", + Responses: map[int][]framework.Response{ + http.StatusNoContent: {{ + Description: "OK", + }}, + }, }, }, HelpSynopsis: strings.TrimSpace(sysHelp["auth_tune"][0]), @@ -1697,6 +1790,65 @@ func (b *SystemBackend) authPaths() []*framework.Path { logical.ReadOperation: &framework.PathOperation{ Callback: b.handleReadAuth, Summary: "Read the configuration of the auth engine at the given path.", + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + Fields: map[string]*framework.FieldSchema{ + "type": { + Type: framework.TypeString, + Required: true, + }, + "description": { + Type: framework.TypeString, + Required: true, + }, + "accessor": { + Type: framework.TypeString, + Required: true, + }, + "local": { + Type: framework.TypeBool, + Required: true, + }, + "seal_wrap": { + Type: framework.TypeBool, + Required: true, + }, + "external_entropy_access": { + Type: framework.TypeBool, + Required: true, + }, + "options": { + Type: framework.TypeMap, + Required: true, + }, + "uuid": { + Type: framework.TypeString, + Required: true, + }, + "plugin_version": { + Type: framework.TypeString, + Required: true, + }, + "running_plugin_version": { + Type: framework.TypeString, + Required: true, + }, + "running_sha256": { + Type: framework.TypeString, + Required: true, + }, + "deprecation_status": { + Type: framework.TypeString, + Required: false, + }, + "config": { + Type: framework.TypeMap, + Required: true, + }, + }, + }}, + }, }, logical.UpdateOperation: &framework.PathOperation{ Callback: b.handleEnableAuth, @@ -1704,10 +1856,20 @@ func (b *SystemBackend) authPaths() []*framework.Path { Description: `After enabling, the auth method can be accessed and configured via the auth path specified as part of the URL. This auth path will be nested under the auth prefix. For example, enable the "foo" auth method will make it accessible at /auth/foo.`, + Responses: map[int][]framework.Response{ + http.StatusNoContent: {{ + Description: "OK", + }}, + }, }, logical.DeleteOperation: &framework.PathOperation{ Callback: b.handleDisableAuth, Summary: "Disable the auth method at the given auth path", + Responses: map[int][]framework.Response{ + http.StatusNoContent: {{ + Description: "OK", + }}, + }, }, }, HelpSynopsis: strings.TrimSpace(sysHelp["auth"][0]), diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 7903ad67fb60..0c857991d8b1 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -1835,6 +1835,12 @@ func TestSystemBackend_authTable(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) exp := map[string]interface{}{ "token/": map[string]interface{}{ @@ -1866,6 +1872,13 @@ func TestSystemBackend_authTable(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) + if diff := deep.Equal(resp.Data, exp["token/"]); diff != nil { t.Fatal(diff) } @@ -1893,6 +1906,12 @@ func TestSystemBackend_enableAuth(t *testing.T) { if resp != nil { t.Fatalf("bad: %v", resp) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) req = logical.TestRequest(t, logical.ReadOperation, "auth") resp, err = b.HandleRequest(namespace.RootContext(nil), req) @@ -1902,6 +1921,12 @@ func TestSystemBackend_enableAuth(t *testing.T) { if resp == nil { t.Fatal("resp is nil") } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) exp := map[string]interface{}{ "foo/": map[string]interface{}{ @@ -1981,6 +2006,12 @@ func TestSystemBackend_disableAuth(t *testing.T) { if resp != nil { t.Fatalf("bad: %v", resp) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) } func TestSystemBackend_tuneAuth(t *testing.T) { @@ -1997,6 +2028,12 @@ func TestSystemBackend_tuneAuth(t *testing.T) { if resp == nil { t.Fatal("resp is nil") } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) exp := map[string]interface{}{ "description": "token based credentials", @@ -2018,6 +2055,13 @@ func TestSystemBackend_tuneAuth(t *testing.T) { t.Fatalf("expected tune request to fail, but got resp: %#v, err: %s", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) + // Register the plugin in the catalog, and then try the same request again. { tempDir, err := filepath.EvalSymlinks(t.TempDir()) @@ -2051,6 +2095,12 @@ func TestSystemBackend_tuneAuth(t *testing.T) { if resp == nil { t.Fatal("resp is nil") } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) if resp.Data["description"] != "" { t.Fatalf("got: %#v expect: %#v", resp.Data["description"], "")