1package awsauth 2 3import ( 4 "context" 5 "fmt" 6 7 "github.com/hashicorp/vault/sdk/framework" 8 "github.com/hashicorp/vault/sdk/logical" 9) 10 11const ( 12 identityWhitelistConfigPath = "config/tidy/identity-whitelist" 13) 14 15func pathConfigTidyIdentityWhitelist(b *backend) *framework.Path { 16 return &framework.Path{ 17 Pattern: fmt.Sprintf("%s$", identityWhitelistConfigPath), 18 Fields: map[string]*framework.FieldSchema{ 19 "safety_buffer": &framework.FieldSchema{ 20 Type: framework.TypeDurationSecond, 21 Default: 259200, //72h 22 Description: `The amount of extra time that must have passed beyond the identity's 23expiration, before it is removed from the backend storage.`, 24 }, 25 "disable_periodic_tidy": &framework.FieldSchema{ 26 Type: framework.TypeBool, 27 Default: false, 28 Description: "If set to 'true', disables the periodic tidying of the 'identity-whitelist/<instance_id>' entries.", 29 }, 30 }, 31 32 ExistenceCheck: b.pathConfigTidyIdentityWhitelistExistenceCheck, 33 34 Callbacks: map[logical.Operation]framework.OperationFunc{ 35 logical.CreateOperation: b.pathConfigTidyIdentityWhitelistCreateUpdate, 36 logical.UpdateOperation: b.pathConfigTidyIdentityWhitelistCreateUpdate, 37 logical.ReadOperation: b.pathConfigTidyIdentityWhitelistRead, 38 logical.DeleteOperation: b.pathConfigTidyIdentityWhitelistDelete, 39 }, 40 41 HelpSynopsis: pathConfigTidyIdentityWhitelistHelpSyn, 42 HelpDescription: pathConfigTidyIdentityWhitelistHelpDesc, 43 } 44} 45 46func (b *backend) pathConfigTidyIdentityWhitelistExistenceCheck(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) { 47 entry, err := b.lockedConfigTidyIdentities(ctx, req.Storage) 48 if err != nil { 49 return false, err 50 } 51 return entry != nil, nil 52} 53 54func (b *backend) lockedConfigTidyIdentities(ctx context.Context, s logical.Storage) (*tidyWhitelistIdentityConfig, error) { 55 b.configMutex.RLock() 56 defer b.configMutex.RUnlock() 57 58 return b.nonLockedConfigTidyIdentities(ctx, s) 59} 60 61func (b *backend) nonLockedConfigTidyIdentities(ctx context.Context, s logical.Storage) (*tidyWhitelistIdentityConfig, error) { 62 entry, err := s.Get(ctx, identityWhitelistConfigPath) 63 if err != nil { 64 return nil, err 65 } 66 if entry == nil { 67 return nil, nil 68 } 69 70 var result tidyWhitelistIdentityConfig 71 if err := entry.DecodeJSON(&result); err != nil { 72 return nil, err 73 } 74 return &result, nil 75} 76 77func (b *backend) pathConfigTidyIdentityWhitelistCreateUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 78 b.configMutex.Lock() 79 defer b.configMutex.Unlock() 80 81 configEntry, err := b.nonLockedConfigTidyIdentities(ctx, req.Storage) 82 if err != nil { 83 return nil, err 84 } 85 if configEntry == nil { 86 configEntry = &tidyWhitelistIdentityConfig{} 87 } 88 89 safetyBufferInt, ok := data.GetOk("safety_buffer") 90 if ok { 91 configEntry.SafetyBuffer = safetyBufferInt.(int) 92 } else if req.Operation == logical.CreateOperation { 93 configEntry.SafetyBuffer = data.Get("safety_buffer").(int) 94 } 95 96 disablePeriodicTidyBool, ok := data.GetOk("disable_periodic_tidy") 97 if ok { 98 configEntry.DisablePeriodicTidy = disablePeriodicTidyBool.(bool) 99 } else if req.Operation == logical.CreateOperation { 100 configEntry.DisablePeriodicTidy = data.Get("disable_periodic_tidy").(bool) 101 } 102 103 entry, err := logical.StorageEntryJSON(identityWhitelistConfigPath, configEntry) 104 if err != nil { 105 return nil, err 106 } 107 108 if err := req.Storage.Put(ctx, entry); err != nil { 109 return nil, err 110 } 111 112 return nil, nil 113} 114 115func (b *backend) pathConfigTidyIdentityWhitelistRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 116 clientConfig, err := b.lockedConfigTidyIdentities(ctx, req.Storage) 117 if err != nil { 118 return nil, err 119 } 120 if clientConfig == nil { 121 return nil, nil 122 } 123 124 return &logical.Response{ 125 Data: map[string]interface{}{ 126 "safety_buffer": clientConfig.SafetyBuffer, 127 "disable_periodic_tidy": clientConfig.DisablePeriodicTidy, 128 }, 129 }, nil 130} 131 132func (b *backend) pathConfigTidyIdentityWhitelistDelete(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { 133 b.configMutex.Lock() 134 defer b.configMutex.Unlock() 135 136 return nil, req.Storage.Delete(ctx, identityWhitelistConfigPath) 137} 138 139type tidyWhitelistIdentityConfig struct { 140 SafetyBuffer int `json:"safety_buffer"` 141 DisablePeriodicTidy bool `json:"disable_periodic_tidy"` 142} 143 144const pathConfigTidyIdentityWhitelistHelpSyn = ` 145Configures the periodic tidying operation of the whitelisted identity entries. 146` 147const pathConfigTidyIdentityWhitelistHelpDesc = ` 148By default, the expired entries in the whitelist will be attempted to be removed 149periodically. This operation will look for expired items in the list and purges them. 150However, there is a safety buffer duration (defaults to 72h), purges the entries 151only if they have been persisting this duration, past its expiration time. 152` 153