From ee842266cb5228edd0976a19d5587ff64878abb9 Mon Sep 17 00:00:00 2001 From: Alejandro Acevedo Date: Fri, 20 Jun 2025 15:51:52 +0200 Subject: [PATCH] STAC-22196: Allow setting a dedicated subject on a service token --- cmd/servicetoken/servicetoken_create.go | 13 +++--- cmd/servicetoken/servicetoken_list.go | 4 +- cmd/servicetoken/servicetoken_list_test.go | 6 +-- generated/stackstate_api/README.md | 2 +- generated/stackstate_api/api/openapi.yaml | 16 ++++++- .../stackstate_api/api_user_authorization.go | 29 +++++++++---- .../docs/NewServiceTokenRequest.md | 26 ++++++++++++ generated/stackstate_api/docs/ServiceToken.md | 26 ++++++++++++ .../docs/UserAuthorizationApi.md | 10 +++-- .../model_new_service_token_request.go | 42 +++++++++++++++++-- .../stackstate_api/model_service_token.go | 36 ++++++++++++++++ stackstate_openapi/openapi_version | 2 +- 12 files changed, 182 insertions(+), 30 deletions(-) diff --git a/cmd/servicetoken/servicetoken_create.go b/cmd/servicetoken/servicetoken_create.go index 4f5a6129..e447cd31 100644 --- a/cmd/servicetoken/servicetoken_create.go +++ b/cmd/servicetoken/servicetoken_create.go @@ -16,9 +16,10 @@ const ( ) type CreateArgs struct { - Name string - Expiration time.Time - Roles []string + Name string + Expiration time.Time + Roles []string + DedicatedSubject string } func CreateCommand(deps *di.Deps) *cobra.Command { @@ -33,6 +34,7 @@ func CreateCommand(deps *di.Deps) *cobra.Command { common.AddRequiredNameFlagVar(cmd, &args.Name, "Name of the service token") cmd.Flags().TimeVar(&args.Expiration, "expiration", time.Time{}, []string{DateFormat}, "Expiration date of the service token") cmd.Flags().StringSliceVar(&args.Roles, "roles", []string{}, "Roles assigned to the service token") + cmd.Flags().StringVar(&args.DedicatedSubject, "dedicatedSubject", "", "Subject solely created for usage with this token. The dedicated subject is cleaned after the token is deleted") cmd.MarkFlagRequired("roles") //nolint:errcheck return cmd } @@ -40,8 +42,9 @@ func CreateCommand(deps *di.Deps) *cobra.Command { func RunServiceTokenCreateCommand(args *CreateArgs) di.CmdWithApiFn { return func(cmd *cobra.Command, cli *di.Deps, api *stackstate_api.APIClient, serverInfo *stackstate_api.ServerInfo) common.CLIError { req := stackstate_api.NewServiceTokenRequest{ - Name: args.Name, - Roles: args.Roles, + Name: args.Name, + Roles: args.Roles, + DedicatedSubject: &args.DedicatedSubject, } if !args.Expiration.IsZero() { diff --git a/cmd/servicetoken/servicetoken_list.go b/cmd/servicetoken/servicetoken_list.go index 57400965..fa89848b 100644 --- a/cmd/servicetoken/servicetoken_list.go +++ b/cmd/servicetoken/servicetoken_list.go @@ -44,11 +44,11 @@ func RunServiceTokenListCommand(cmd *cobra.Command, cli *di.Deps, api *stackstat if serviceToken.Expiration != nil { exp = time.UnixMilli(*serviceToken.Expiration).Format(DateFormat) } - data = append(data, []interface{}{sid, serviceToken.Name, exp, serviceToken.Roles}) + data = append(data, []interface{}{sid, serviceToken.Name, exp, serviceToken.Roles, serviceToken.DedicatedSubject}) } cli.Printer.Table(printer.TableData{ - Header: []string{"id", "name", "expiration", "roles"}, + Header: []string{"id", "name", "expiration", "roles", "dedicated_Subject"}, Data: data, MissingTableDataMsg: printer.NotFoundMsg{Types: "service tokens"}, }) diff --git a/cmd/servicetoken/servicetoken_list_test.go b/cmd/servicetoken/servicetoken_list_test.go index 33d89243..c995f630 100644 --- a/cmd/servicetoken/servicetoken_list_test.go +++ b/cmd/servicetoken/servicetoken_list_test.go @@ -37,10 +37,10 @@ func TestServiceTokenList(t *testing.T) { tableData := []printer.TableData{ { - Header: []string{"id", "name", "expiration", "roles"}, + Header: []string{"id", "name", "expiration", "roles", "dedicated_Subject"}, Data: [][]interface{}{ - {int64(1), "test", "2020-05-22", []string{"test-role", "another-role"}}, - {int64(2), "test2", "", []string{"test-role"}}, + {int64(1), "test", "2020-05-22", []string{"test-role", "another-role"}, (*string)(nil)}, + {int64(2), "test2", "", []string{"test-role"}, (*string)(nil)}, }, MissingTableDataMsg: printer.NotFoundMsg{Types: "service tokens"}, }, diff --git a/generated/stackstate_api/README.md b/generated/stackstate_api/README.md index 42ce4ffd..9f104ca1 100644 --- a/generated/stackstate_api/README.md +++ b/generated/stackstate_api/README.md @@ -232,7 +232,7 @@ Class | Method | HTTP request | Description *TracesApi* | [**SuggestionsAttributeName**](docs/TracesApi.md#suggestionsattributename) | **Get** /traces/spans/fields/attributes | Suggestions for attribute names *TracesApi* | [**SuggestionsAttributeValue**](docs/TracesApi.md#suggestionsattributevalue) | **Get** /traces/spans/fields/attributes/{attributeName}/values | Suggestions for attribute values *TracesApi* | [**SuggestionsFieldValues**](docs/TracesApi.md#suggestionsfieldvalues) | **Get** /traces/spans/fields/{field}/values | Suggestions for span fields -*UserAuthorizationApi* | [**GetUserAuthorizationFor**](docs/UserAuthorizationApi.md#getuserauthorizationfor) | **Get** /user/authorization/for | Is the current user authorized for the provided permission +*UserAuthorizationApi* | [**GetUserAuthorizationFor**](docs/UserAuthorizationApi.md#getuserauthorizationfor) | **Get** /user/authorization/for | Is the current user authorized for the provided permission and resource *UserProfileApi* | [**GetCurrentUserProfile**](docs/UserProfileApi.md#getcurrentuserprofile) | **Get** /user/profile | Get current user profile *UserProfileApi* | [**SaveCurrentUserProfile**](docs/UserProfileApi.md#savecurrentuserprofile) | **Put** /user/profile | Save current user profile *UserSessionApi* | [**GetUserSessionAssumedRole**](docs/UserSessionApi.md#getusersessionassumedrole) | **Get** /user/session/assumedRole | Get the assumed a role for the current session diff --git a/generated/stackstate_api/api/openapi.yaml b/generated/stackstate_api/api/openapi.yaml index 9d3bc9e8..e691a8d3 100644 --- a/generated/stackstate_api/api/openapi.yaml +++ b/generated/stackstate_api/api/openapi.yaml @@ -2596,7 +2596,8 @@ paths: - userSession /user/authorization/for: get: - description: Is the current user authorized for the provided permission + description: Is the current user authorized for the provided permission and + resource operationId: getUserAuthorizationFor parameters: - in: query @@ -2604,6 +2605,11 @@ paths: required: true schema: type: string + - in: query + name: resourceName + required: false + schema: + type: string responses: "204": description: User is authorized @@ -2619,7 +2625,7 @@ paths: schema: $ref: '#/components/schemas/GenericErrorsResponse' description: Error when handling the request on the server side. - summary: Is the current user authorized for the provided permission + summary: Is the current user authorized for the provided permission and resource tags: - userAuthorization /events: @@ -10685,6 +10691,7 @@ components: - roles - roles name: name + dedicatedSubject: dedicatedSubject properties: name: type: string @@ -10695,6 +10702,8 @@ components: items: type: string type: array + dedicatedSubject: + type: string required: - name - roles @@ -10709,6 +10718,7 @@ components: description: description expiration: 1 id: 0 + dedicatedSubject: dedicatedSubject properties: id: format: int64 @@ -10729,6 +10739,8 @@ components: items: type: string type: array + dedicatedSubject: + type: string required: - name - roles diff --git a/generated/stackstate_api/api_user_authorization.go b/generated/stackstate_api/api_user_authorization.go index 9bcc3648..2fd57727 100644 --- a/generated/stackstate_api/api_user_authorization.go +++ b/generated/stackstate_api/api_user_authorization.go @@ -22,9 +22,9 @@ import ( type UserAuthorizationApi interface { /* - GetUserAuthorizationFor Is the current user authorized for the provided permission + GetUserAuthorizationFor Is the current user authorized for the provided permission and resource - Is the current user authorized for the provided permission + Is the current user authorized for the provided permission and resource @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @return ApiGetUserAuthorizationForRequest @@ -39,9 +39,10 @@ type UserAuthorizationApi interface { type UserAuthorizationApiService service type ApiGetUserAuthorizationForRequest struct { - ctx context.Context - ApiService UserAuthorizationApi - permission *string + ctx context.Context + ApiService UserAuthorizationApi + permission *string + resourceName *string } func (r ApiGetUserAuthorizationForRequest) Permission(permission string) ApiGetUserAuthorizationForRequest { @@ -49,14 +50,19 @@ func (r ApiGetUserAuthorizationForRequest) Permission(permission string) ApiGetU return r } +func (r ApiGetUserAuthorizationForRequest) ResourceName(resourceName string) ApiGetUserAuthorizationForRequest { + r.resourceName = &resourceName + return r +} + func (r ApiGetUserAuthorizationForRequest) Execute() (*http.Response, error) { return r.ApiService.GetUserAuthorizationForExecute(r) } /* -GetUserAuthorizationFor Is the current user authorized for the provided permission +GetUserAuthorizationFor Is the current user authorized for the provided permission and resource -Is the current user authorized for the provided permission +Is the current user authorized for the provided permission and resource @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @return ApiGetUserAuthorizationForRequest @@ -91,6 +97,9 @@ func (a *UserAuthorizationApiService) GetUserAuthorizationForExecute(r ApiGetUse } localVarQueryParams.Add("permission", parameterToString(*r.permission, "")) + if r.resourceName != nil { + localVarQueryParams.Add("resourceName", parameterToString(*r.resourceName, "")) + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -209,7 +218,8 @@ type GetUserAuthorizationForMockResponse struct { } type GetUserAuthorizationForCall struct { - Ppermission *string + Ppermission *string + PresourceName *string } func (mock UserAuthorizationApiMock) GetUserAuthorizationFor(ctx context.Context) ApiGetUserAuthorizationForRequest { @@ -221,7 +231,8 @@ func (mock UserAuthorizationApiMock) GetUserAuthorizationFor(ctx context.Context func (mock UserAuthorizationApiMock) GetUserAuthorizationForExecute(r ApiGetUserAuthorizationForRequest) (*http.Response, error) { p := GetUserAuthorizationForCall{ - Ppermission: r.permission, + Ppermission: r.permission, + PresourceName: r.resourceName, } *mock.GetUserAuthorizationForCalls = append(*mock.GetUserAuthorizationForCalls, p) return mock.GetUserAuthorizationForResponse.Response, mock.GetUserAuthorizationForResponse.Error diff --git a/generated/stackstate_api/docs/NewServiceTokenRequest.md b/generated/stackstate_api/docs/NewServiceTokenRequest.md index d6820257..8255fcb5 100644 --- a/generated/stackstate_api/docs/NewServiceTokenRequest.md +++ b/generated/stackstate_api/docs/NewServiceTokenRequest.md @@ -7,6 +7,7 @@ Name | Type | Description | Notes **Name** | **string** | | **ExpiryDate** | Pointer to **int64** | | [optional] **Roles** | **[]string** | | +**DedicatedSubject** | Pointer to **string** | | [optional] ## Methods @@ -92,6 +93,31 @@ and a boolean to check if the value has been set. SetRoles sets Roles field to given value. +### GetDedicatedSubject + +`func (o *NewServiceTokenRequest) GetDedicatedSubject() string` + +GetDedicatedSubject returns the DedicatedSubject field if non-nil, zero value otherwise. + +### GetDedicatedSubjectOk + +`func (o *NewServiceTokenRequest) GetDedicatedSubjectOk() (*string, bool)` + +GetDedicatedSubjectOk returns a tuple with the DedicatedSubject field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDedicatedSubject + +`func (o *NewServiceTokenRequest) SetDedicatedSubject(v string)` + +SetDedicatedSubject sets DedicatedSubject field to given value. + +### HasDedicatedSubject + +`func (o *NewServiceTokenRequest) HasDedicatedSubject() bool` + +HasDedicatedSubject returns a boolean if a field has been set. + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/stackstate_api/docs/ServiceToken.md b/generated/stackstate_api/docs/ServiceToken.md index 778af67a..2c484a27 100644 --- a/generated/stackstate_api/docs/ServiceToken.md +++ b/generated/stackstate_api/docs/ServiceToken.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **Description** | Pointer to **string** | | [optional] **Expiration** | Pointer to **int64** | | [optional] **Roles** | **[]string** | | +**DedicatedSubject** | Pointer to **string** | | [optional] ## Methods @@ -170,6 +171,31 @@ and a boolean to check if the value has been set. SetRoles sets Roles field to given value. +### GetDedicatedSubject + +`func (o *ServiceToken) GetDedicatedSubject() string` + +GetDedicatedSubject returns the DedicatedSubject field if non-nil, zero value otherwise. + +### GetDedicatedSubjectOk + +`func (o *ServiceToken) GetDedicatedSubjectOk() (*string, bool)` + +GetDedicatedSubjectOk returns a tuple with the DedicatedSubject field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDedicatedSubject + +`func (o *ServiceToken) SetDedicatedSubject(v string)` + +SetDedicatedSubject sets DedicatedSubject field to given value. + +### HasDedicatedSubject + +`func (o *ServiceToken) HasDedicatedSubject() bool` + +HasDedicatedSubject returns a boolean if a field has been set. + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/stackstate_api/docs/UserAuthorizationApi.md b/generated/stackstate_api/docs/UserAuthorizationApi.md index e34e3f1c..bffd6bb1 100644 --- a/generated/stackstate_api/docs/UserAuthorizationApi.md +++ b/generated/stackstate_api/docs/UserAuthorizationApi.md @@ -4,15 +4,15 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GetUserAuthorizationFor**](UserAuthorizationApi.md#GetUserAuthorizationFor) | **Get** /user/authorization/for | Is the current user authorized for the provided permission +[**GetUserAuthorizationFor**](UserAuthorizationApi.md#GetUserAuthorizationFor) | **Get** /user/authorization/for | Is the current user authorized for the provided permission and resource ## GetUserAuthorizationFor -> GetUserAuthorizationFor(ctx).Permission(permission).Execute() +> GetUserAuthorizationFor(ctx).Permission(permission).ResourceName(resourceName).Execute() -Is the current user authorized for the provided permission +Is the current user authorized for the provided permission and resource @@ -30,10 +30,11 @@ import ( func main() { permission := "permission_example" // string | + resourceName := "resourceName_example" // string | (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.UserAuthorizationApi.GetUserAuthorizationFor(context.Background()).Permission(permission).Execute() + resp, r, err := apiClient.UserAuthorizationApi.GetUserAuthorizationFor(context.Background()).Permission(permission).ResourceName(resourceName).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `UserAuthorizationApi.GetUserAuthorizationFor``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -53,6 +54,7 @@ Other parameters are passed through a pointer to a apiGetUserAuthorizationForReq Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **permission** | **string** | | + **resourceName** | **string** | | ### Return type diff --git a/generated/stackstate_api/model_new_service_token_request.go b/generated/stackstate_api/model_new_service_token_request.go index c68d1015..b4f332f5 100644 --- a/generated/stackstate_api/model_new_service_token_request.go +++ b/generated/stackstate_api/model_new_service_token_request.go @@ -17,9 +17,10 @@ import ( // NewServiceTokenRequest struct for NewServiceTokenRequest type NewServiceTokenRequest struct { - Name string `json:"name"` - ExpiryDate *int64 `json:"expiryDate,omitempty"` - Roles []string `json:"roles"` + Name string `json:"name"` + ExpiryDate *int64 `json:"expiryDate,omitempty"` + Roles []string `json:"roles"` + DedicatedSubject *string `json:"dedicatedSubject,omitempty"` } // NewNewServiceTokenRequest instantiates a new NewServiceTokenRequest object @@ -121,6 +122,38 @@ func (o *NewServiceTokenRequest) SetRoles(v []string) { o.Roles = v } +// GetDedicatedSubject returns the DedicatedSubject field value if set, zero value otherwise. +func (o *NewServiceTokenRequest) GetDedicatedSubject() string { + if o == nil || o.DedicatedSubject == nil { + var ret string + return ret + } + return *o.DedicatedSubject +} + +// GetDedicatedSubjectOk returns a tuple with the DedicatedSubject field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *NewServiceTokenRequest) GetDedicatedSubjectOk() (*string, bool) { + if o == nil || o.DedicatedSubject == nil { + return nil, false + } + return o.DedicatedSubject, true +} + +// HasDedicatedSubject returns a boolean if a field has been set. +func (o *NewServiceTokenRequest) HasDedicatedSubject() bool { + if o != nil && o.DedicatedSubject != nil { + return true + } + + return false +} + +// SetDedicatedSubject gets a reference to the given string and assigns it to the DedicatedSubject field. +func (o *NewServiceTokenRequest) SetDedicatedSubject(v string) { + o.DedicatedSubject = &v +} + func (o NewServiceTokenRequest) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if true { @@ -132,6 +165,9 @@ func (o NewServiceTokenRequest) MarshalJSON() ([]byte, error) { if true { toSerialize["roles"] = o.Roles } + if o.DedicatedSubject != nil { + toSerialize["dedicatedSubject"] = o.DedicatedSubject + } return json.Marshal(toSerialize) } diff --git a/generated/stackstate_api/model_service_token.go b/generated/stackstate_api/model_service_token.go index 6749c6a4..e8cd4c9e 100644 --- a/generated/stackstate_api/model_service_token.go +++ b/generated/stackstate_api/model_service_token.go @@ -23,6 +23,7 @@ type ServiceToken struct { Description *string `json:"description,omitempty"` Expiration *int64 `json:"expiration,omitempty"` Roles []string `json:"roles"` + DedicatedSubject *string `json:"dedicatedSubject,omitempty"` } // NewServiceToken instantiates a new ServiceToken object @@ -220,6 +221,38 @@ func (o *ServiceToken) SetRoles(v []string) { o.Roles = v } +// GetDedicatedSubject returns the DedicatedSubject field value if set, zero value otherwise. +func (o *ServiceToken) GetDedicatedSubject() string { + if o == nil || o.DedicatedSubject == nil { + var ret string + return ret + } + return *o.DedicatedSubject +} + +// GetDedicatedSubjectOk returns a tuple with the DedicatedSubject field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServiceToken) GetDedicatedSubjectOk() (*string, bool) { + if o == nil || o.DedicatedSubject == nil { + return nil, false + } + return o.DedicatedSubject, true +} + +// HasDedicatedSubject returns a boolean if a field has been set. +func (o *ServiceToken) HasDedicatedSubject() bool { + if o != nil && o.DedicatedSubject != nil { + return true + } + + return false +} + +// SetDedicatedSubject gets a reference to the given string and assigns it to the DedicatedSubject field. +func (o *ServiceToken) SetDedicatedSubject(v string) { + o.DedicatedSubject = &v +} + func (o ServiceToken) MarshalJSON() ([]byte, error) { toSerialize := map[string]interface{}{} if o.Id != nil { @@ -240,6 +273,9 @@ func (o ServiceToken) MarshalJSON() ([]byte, error) { if true { toSerialize["roles"] = o.Roles } + if o.DedicatedSubject != nil { + toSerialize["dedicatedSubject"] = o.DedicatedSubject + } return json.Marshal(toSerialize) } diff --git a/stackstate_openapi/openapi_version b/stackstate_openapi/openapi_version index 7a3669dd..0f9debce 100644 --- a/stackstate_openapi/openapi_version +++ b/stackstate_openapi/openapi_version @@ -1 +1 @@ -69b0921eca6bff1d2a3d8ad6327fc171571797ad +c2781061affeff4c6e18f69904fa15bce9a09e05