From 1db3b1b15937fef1bebe93733bbb8b60cfb183b2 Mon Sep 17 00:00:00 2001 From: ncabatoff Date: Tue, 31 Oct 2023 08:55:46 -0400 Subject: [PATCH 1/7] Make the internal UI mount read match what tune read does, by using the default TTLs when mount-specific settings aren't in use. --- vault/logical_system.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index c2e0848bfca2..a1a519ebc6e8 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -1180,10 +1180,17 @@ func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry) map[st "running_sha256": entry.RunningSha256, } entryConfig := map[string]interface{}{ - "default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()), - "max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()), + "default_lease_ttl": b.Core.defaultLeaseTTL, + "max_lease_ttl": b.Core.maxLeaseTTL, "force_no_cache": entry.Config.ForceNoCache, } + if defttl := int64(entry.Config.DefaultLeaseTTL.Seconds()); defttl != 0 { + entryConfig["default_lease_ttl"] = defttl + } + if maxttl := int64(entry.Config.MaxLeaseTTL.Seconds()); maxttl != 0 { + entryConfig["default_lease_ttl"] = maxttl + } + if rawVal, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok { entryConfig["audit_non_hmac_request_keys"] = rawVal.([]string) } From 98655d00c4d254e18f96acd52dc25d3a00146f94 Mon Sep 17 00:00:00 2001 From: ncabatoff Date: Fri, 15 Dec 2023 15:06:18 -0500 Subject: [PATCH 2/7] Fix a couple of bugs --- vault/logical_system.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index a1a519ebc6e8..3815a63beb91 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -1180,15 +1180,15 @@ func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry) map[st "running_sha256": entry.RunningSha256, } entryConfig := map[string]interface{}{ - "default_lease_ttl": b.Core.defaultLeaseTTL, - "max_lease_ttl": b.Core.maxLeaseTTL, + "default_lease_ttl": b.Core.defaultLeaseTTL.Seconds(), + "max_lease_ttl": b.Core.maxLeaseTTL.Seconds(), "force_no_cache": entry.Config.ForceNoCache, } if defttl := int64(entry.Config.DefaultLeaseTTL.Seconds()); defttl != 0 { entryConfig["default_lease_ttl"] = defttl } if maxttl := int64(entry.Config.MaxLeaseTTL.Seconds()); maxttl != 0 { - entryConfig["default_lease_ttl"] = maxttl + entryConfig["max_lease_ttl"] = maxttl } if rawVal, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok { From e353779d9f4234644b02f77c7c3c1bb86d9a399f Mon Sep 17 00:00:00 2001 From: ncabatoff Date: Thu, 21 Dec 2023 13:19:39 -0500 Subject: [PATCH 3/7] Limit impact of change to UI-specific endpoints --- vault/logical_system.go | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 3815a63beb91..8a15848e472a 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -1165,7 +1165,7 @@ func (b *SystemBackend) handleGenerateRootDecodeTokenUpdate(ctx context.Context, return resp, nil } -func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry) map[string]interface{} { +func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry, legacyTTLFormat bool) map[string]interface{} { info := map[string]interface{}{ "type": entry.Type, "description": entry.Description, @@ -1179,16 +1179,22 @@ func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry) map[st "running_plugin_version": entry.RunningVersion, "running_sha256": entry.RunningSha256, } + coreDefTTL := int64(b.Core.defaultLeaseTTL.Seconds()) + coreMaxTTL := int64(b.Core.maxLeaseTTL.Seconds()) + entDefTTL := int64(entry.Config.DefaultLeaseTTL.Seconds()) + entMaxTTL := int64(entry.Config.MaxLeaseTTL.Seconds()) entryConfig := map[string]interface{}{ - "default_lease_ttl": b.Core.defaultLeaseTTL.Seconds(), - "max_lease_ttl": b.Core.maxLeaseTTL.Seconds(), + "default_lease_ttl": entDefTTL, + "max_lease_ttl": entMaxTTL, "force_no_cache": entry.Config.ForceNoCache, } - if defttl := int64(entry.Config.DefaultLeaseTTL.Seconds()); defttl != 0 { - entryConfig["default_lease_ttl"] = defttl - } - if maxttl := int64(entry.Config.MaxLeaseTTL.Seconds()); maxttl != 0 { - entryConfig["max_lease_ttl"] = maxttl + if !legacyTTLFormat { + if entDefTTL == 0 { + entryConfig["default_lease_ttl"] = coreDefTTL + } + if entMaxTTL == 0 { + entryConfig["max_lease_ttl"] = coreMaxTTL + } } if rawVal, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok { @@ -1263,7 +1269,7 @@ func (b *SystemBackend) handleMountTable(ctx context.Context, req *logical.Reque } // Populate mount info - info := b.mountInfo(ctx, entry) + info := b.mountInfo(ctx, entry, true) resp.Data[entry.Path] = info } @@ -1504,7 +1510,7 @@ func (b *SystemBackend) handleReadMount(ctx context.Context, req *logical.Reques } return &logical.Response{ - Data: b.mountInfo(ctx, entry), + Data: b.mountInfo(ctx, entry, true), }, nil } @@ -2692,7 +2698,7 @@ func (b *SystemBackend) handleAuthTable(ctx context.Context, req *logical.Reques continue } - info := b.mountInfo(ctx, entry) + info := b.mountInfo(ctx, entry, true) resp.Data[entry.Path] = info } @@ -2726,7 +2732,7 @@ func (b *SystemBackend) handleReadAuth(ctx context.Context, req *logical.Request } return &logical.Response{ - Data: b.mountInfo(ctx, entry), + Data: b.mountInfo(ctx, entry, true), }, nil } @@ -4481,7 +4487,7 @@ func (b *SystemBackend) pathInternalUIMountsRead(ctx context.Context, req *logic if ns.ID == entry.NamespaceID && hasAccess(ctx, entry) { if isAuthed { // If this is an authed request return all the mount info - secretMounts[entry.Path] = b.mountInfo(ctx, entry) + secretMounts[entry.Path] = b.mountInfo(ctx, entry, false) } else { secretMounts[entry.Path] = map[string]interface{}{ "type": entry.Type, @@ -4508,7 +4514,7 @@ func (b *SystemBackend) pathInternalUIMountsRead(ctx context.Context, req *logic if ns.ID == entry.NamespaceID && hasAccess(ctx, entry) { if isAuthed { // If this is an authed request return all the mount info - authMounts[entry.Path] = b.mountInfo(ctx, entry) + authMounts[entry.Path] = b.mountInfo(ctx, entry, false) } else { authMounts[entry.Path] = map[string]interface{}{ "type": entry.Type, @@ -4571,7 +4577,7 @@ func (b *SystemBackend) pathInternalUIMountRead(ctx context.Context, req *logica return errResp, logical.ErrPermissionDenied } resp := &logical.Response{ - Data: b.mountInfo(ctx, me), + Data: b.mountInfo(ctx, me, false), } resp.Data["path"] = me.Path From 5b2d937a7b29496a93f14ef088730814815de9ed Mon Sep 17 00:00:00 2001 From: ncabatoff Date: Thu, 21 Dec 2023 14:03:19 -0500 Subject: [PATCH 4/7] Fix test --- vault/logical_system_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 99cdc037ff08..0f27af0bbe77 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -3961,8 +3961,8 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "token/": map[string]interface{}{ "options": map[string]string(nil), "config": map[string]interface{}{ - "default_lease_ttl": int64(0), - "max_lease_ttl": int64(0), + "default_lease_ttl": int64(2764800), + "max_lease_ttl": int64(2764800), "force_no_cache": false, "token_type": "default-service", }, From 40b828495173924d4736ef0fd2d5ad683adedfee Mon Sep 17 00:00:00 2001 From: "clairebontempo@gmail.com" Date: Thu, 25 Apr 2024 17:18:54 -0700 Subject: [PATCH 5/7] refactor findAll to use internal/ui/mounts when authenticated as well --- ui/app/adapters/auth-method.js | 35 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/ui/app/adapters/auth-method.js b/ui/app/adapters/auth-method.js index 449383911bb1..3958d46eeb19 100644 --- a/ui/app/adapters/auth-method.js +++ b/ui/app/adapters/auth-method.js @@ -21,28 +21,21 @@ export default ApplicationAdapter.extend({ findAll(store, type, sinceToken, snapshotRecordArray) { const isUnauthenticated = snapshotRecordArray?.adapterOptions?.unauthenticated; - if (isUnauthenticated) { - const url = `/${this.urlPrefix()}/internal/ui/mounts`; - return this.ajax(url, 'GET', { - unauthenticated: true, + const url = `/${this.urlPrefix()}/internal/ui/mounts`; + return this.ajax(url, 'GET', { unauthenticated: isUnauthenticated }) + .then((result) => { + return { + data: result.data.auth, + }; }) - .then((result) => { - return { - data: result.data.auth, - }; - }) - .catch(() => { - return { - data: {}, - }; - }); - } - return this.ajax(this.url(), 'GET').catch((e) => { - if (e instanceof AdapterError) { - set(e, 'policyPath', 'sys/auth'); - } - throw e; - }); + .catch((e) => { + if (isUnauthenticated) { + return { data: {} }; + } else if (e instanceof AdapterError) { + set(e, 'policyPath', 'sys/auth'); + } + throw e; + }); }, createRecord(store, type, snapshot) { From 840f96f032dcf0a0c2cb5a396bf5d8cb01c6b51f Mon Sep 17 00:00:00 2001 From: "clairebontempo@gmail.com" Date: Thu, 25 Apr 2024 17:43:40 -0700 Subject: [PATCH 6/7] format ttl in details view --- ui/app/templates/components/auth-method/configuration.hbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/app/templates/components/auth-method/configuration.hbs b/ui/app/templates/components/auth-method/configuration.hbs index bddbfdc139f1..9c5b85e060bc 100644 --- a/ui/app/templates/components/auth-method/configuration.hbs +++ b/ui/app/templates/components/auth-method/configuration.hbs @@ -10,12 +10,14 @@ @alwaysRender={{not (is-empty-value (get @model attr.name))}} @label={{or attr.options.label (to-label attr.name)}} @value={{stringify (get @model attr.name)}} + @formatTtl={{eq attr.options.editType "ttl"}} /> {{else}} {{/if}} {{/each}} From 0ee782b1b05065d715dd7f5cac5e8f4b67abf26b Mon Sep 17 00:00:00 2001 From: "clairebontempo@gmail.com" Date: Thu, 25 Apr 2024 17:44:06 -0700 Subject: [PATCH 7/7] include hours in format for easy comparison to CLI return --- ui/lib/core/addon/helpers/format-duration.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/lib/core/addon/helpers/format-duration.js b/ui/lib/core/addon/helpers/format-duration.js index be6b9f0c6879..b3b201452a28 100644 --- a/ui/lib/core/addon/helpers/format-duration.js +++ b/ui/lib/core/addon/helpers/format-duration.js @@ -4,7 +4,7 @@ */ import { helper } from '@ember/component/helper'; -import { durationToSeconds } from 'core/utils/duration-utils'; +import { convertFromSeconds, durationToSeconds, largestUnitFromSeconds } from 'core/utils/duration-utils'; import { formatDuration, intervalToDuration } from 'date-fns'; export function duration([time]) { @@ -23,7 +23,10 @@ export function duration([time]) { return '0 seconds'; } // convert to human-readable format: '1 hour 6 seconds' - return formatDuration(durationObject); + let unit = largestUnitFromSeconds(seconds); + if (unit === 'd') unit = 'h'; // highest increment backend returns is hour + const duration = convertFromSeconds(seconds, unit); + return `${formatDuration(durationObject)} (${duration}${unit})`; } return time; }