From 9bfbd38431cd4fc3b2403975dd2b63841668a7f3 Mon Sep 17 00:00:00 2001 From: Paulo Canilho Date: Tue, 27 Feb 2024 21:48:10 +0100 Subject: [PATCH] feat: added a configuration key [hide_repository_metadata] that, if set to true, will minimize the [token.data.repositories] to [token.data.repositories.names] to avoid high memory consumption (#114) --- github/client.go | 13 +++++++++++++ github/config.go | 11 +++++++++++ github/path_config.go | 26 ++++++++++++++++++-------- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/github/client.go b/github/client.go index 03b8847..14cf3d4 100644 --- a/github/client.go +++ b/github/client.go @@ -95,6 +95,7 @@ func NewClient(config *Config) (*Client, error) { installationsURL := baseURL.ResolveReference(&url.URL{Path: "app/installations"}) return &Client{ + Config: config, revocationURL: baseURL.ResolveReference(&url.URL{Path: "installation/token"}), revocationClient: &http.Client{ Timeout: reqTimeout, @@ -221,6 +222,18 @@ func (c *Client) token(ctx context.Context, tokReq *tokenRequest) (*logical.Resp return nil, fmt.Errorf("%w: %v", errUnableToDecodeAccessTokenRes, err) } + // Reduce memory consumption by reducing 'repositories' metadata to simple list of repository names + if !c.IncludeRepositoryMetadata { + repositoriesKey, included := resData["repositories"] + if included { + repositories := repositoriesKey.([]any) + var repoNames []string + for _, r := range repositories { + repoNames = append(repoNames, r.(map[string]any)["name"].(string)) + } + resData["repositories"] = repoNames + } + } tokRes := &logical.Response{Data: resData} // Enrich the response with what we know about the installation. diff --git a/github/config.go b/github/config.go index 3f5cac7..6f05ad8 100644 --- a/github/config.go +++ b/github/config.go @@ -31,6 +31,10 @@ type Config struct { // BaseURL is the base URL for API requests. // Defaults to GitHub's public API. BaseURL string `json:"base_url"` + + // IncludeRepositoryMetadata controls filtering of the 'repositories' key returned on repository-filtered tokens + // Defaults to returning full repository metadata; returns a minimised list of repository names if set to false + IncludeRepositoryMetadata bool `json:"include_repository_metadata"` } // NewConfig returns a pre-configured Config struct. @@ -79,6 +83,13 @@ func (c *Config) Update(d *framework.FieldData) (bool, error) { } } + if includeRepositoryMetadata, ok := d.GetOk(includeRepositoryMetadataKey); ok { + if nv := includeRepositoryMetadata.(bool); c.IncludeRepositoryMetadata != nv { + c.IncludeRepositoryMetadata = nv + changed = true + } + } + return changed, nil } diff --git a/github/path_config.go b/github/path_config.go index 6595603..b9529ef 100644 --- a/github/path_config.go +++ b/github/path_config.go @@ -19,12 +19,15 @@ const ( ) const ( - keyAppID = "app_id" - descAppID = "Application ID of the GitHub App." - keyPrvKey = "prv_key" - descPrvKey = "Private key for signing GitHub access token requests (JWTs)." - keyBaseURL = "base_url" - descBaseURL = "Base URL for API requests (defaults to the public GitHub API)." + keyAppID = "app_id" + descAppID = "Application ID of the GitHub App." + keyPrvKey = "prv_key" + includeRepositoryMetadataKey = "include_repository_metadata" + + descPrvKey = "Private key for signing GitHub access token requests (JWTs)." + descIncludeRepositoryMetadataKey = "If set to true, the token lease response 'data.repositories' sub-field will be minimized to 'data.repositories.*.names'" + keyBaseURL = "base_url" + descBaseURL = "Base URL for API requests (defaults to the public GitHub API)." ) const pathConfigHelpSyn = ` @@ -51,6 +54,12 @@ func (b *backend) pathConfig() *framework.Path { Description: descPrvKey, Required: true, }, + includeRepositoryMetadataKey: { + Type: framework.TypeBool, + Description: descIncludeRepositoryMetadataKey, + Required: false, + Default: true, + }, keyBaseURL: { Type: framework.TypeString, Description: descBaseURL, @@ -87,8 +96,9 @@ func (b *backend) pathConfigRead( } resData := map[string]any{ - keyAppID: c.AppID, - keyBaseURL: c.BaseURL, + keyAppID: c.AppID, + keyBaseURL: c.BaseURL, + includeRepositoryMetadataKey: c.IncludeRepositoryMetadata, } // We don't return the key but indicate its presence for a better UX.