Use mutex in OIDC configuration handlers (#12932)

This commit is contained in:
Austin Gebauer 2021-10-27 08:23:05 -07:00 committed by GitHub
parent e8f14b451b
commit b3fab954fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 13 deletions

3
changelog/12932.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:feature
**OIDC Identity Provider (Tech Preview)**: Adds support for Vault to be an OpenID Connect (OIDC) provider.
```

View File

@ -607,6 +607,9 @@ func (i *IdentityStore) providersReferencingTargetScopeName(ctx context.Context,
func (i *IdentityStore) pathOIDCCreateUpdateAssignment(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
var assignment assignment
if req.Operation == logical.UpdateOperation {
entry, err := req.Storage.Get(ctx, assignmentPath+name)
@ -699,6 +702,9 @@ func (i *IdentityStore) getOIDCAssignment(ctx context.Context, s logical.Storage
func (i *IdentityStore) pathOIDCDeleteAssignment(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
clientNames, err := i.clientNamesReferencingTargetAssignmentName(ctx, req, name)
if err != nil {
return nil, err
@ -735,6 +741,9 @@ func (i *IdentityStore) pathOIDCCreateUpdateScope(ctx context.Context, req *logi
return logical.ErrorResponse("the %q scope name is reserved", openIDScope), nil
}
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
var scope scope
if req.Operation == logical.UpdateOperation {
entry, err := req.Storage.Get(ctx, scopePath+name)
@ -848,20 +857,21 @@ func (i *IdentityStore) getOIDCScope(ctx context.Context, s logical.Storage, nam
return &scope, nil
}
// pathOIDCDeleteScope is used to delete an scope
// pathOIDCDeleteScope is used to delete a scope
func (i *IdentityStore) pathOIDCDeleteScope(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
targetScopeName := d.Get("name").(string)
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
providerNames, err := i.providersReferencingTargetScopeName(ctx, req, targetScopeName)
providerNames, err := i.providersReferencingTargetScopeName(ctx, req, name)
if err != nil {
return nil, err
}
if len(providerNames) > 0 {
errorMessage := fmt.Sprintf("unable to delete scope %q because it is currently referenced by these providers: %s",
targetScopeName, strings.Join(providerNames, ", "))
name, strings.Join(providerNames, ", "))
return logical.ErrorResponse(errorMessage), logical.ErrInvalidRequest
}
err = req.Storage.Delete(ctx, scopePath+name)
@ -892,6 +902,9 @@ func (i *IdentityStore) pathOIDCCreateUpdateClient(ctx context.Context, req *log
return nil, err
}
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
client := client{
Name: name,
NamespaceID: ns.ID,
@ -949,18 +962,14 @@ func (i *IdentityStore) pathOIDCCreateUpdateClient(ctx context.Context, req *log
return logical.ErrorResponse("the key parameter is required"), nil
}
var key namedKey
// enforce key existence on client creation
entry, err := req.Storage.Get(ctx, namedKeyConfigPath+client.Key)
key, err := i.getNamedKey(ctx, req.Storage, client.Key)
if err != nil {
return nil, err
}
if entry == nil {
if key == nil {
return logical.ErrorResponse("key %q does not exist", client.Key), nil
}
if err := entry.DecodeJSON(&key); err != nil {
return nil, err
}
if idTokenTTLRaw, ok := d.GetOk("id_token_ttl"); ok {
client.IDTokenTTL = time.Duration(idTokenTTLRaw.(int)) * time.Second
@ -1002,7 +1011,7 @@ func (i *IdentityStore) pathOIDCCreateUpdateClient(ctx context.Context, req *log
}
// store client
entry, err = logical.StorageEntryJSON(clientPath+name, client)
entry, err := logical.StorageEntryJSON(clientPath+name, client)
if err != nil {
return nil, err
}
@ -1047,10 +1056,13 @@ func (i *IdentityStore) pathOIDCReadClient(ctx context.Context, req *logical.Req
}, nil
}
// pathOIDCDeleteClient is used to delete an client
// pathOIDCDeleteClient is used to delete a client
func (i *IdentityStore) pathOIDCDeleteClient(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
// Delete the client from memdb
if err := i.memDBDeleteClientByName(ctx, name); err != nil {
return nil, err
@ -1080,6 +1092,9 @@ func (i *IdentityStore) pathOIDCCreateUpdateProvider(ctx context.Context, req *l
var resp logical.Response
name := d.Get("name").(string)
i.oidcLock.Lock()
defer i.oidcLock.Unlock()
var provider provider
if req.Operation == logical.UpdateOperation {
entry, err := req.Storage.Get(ctx, providerPath+name)
@ -1260,7 +1275,7 @@ func (i *IdentityStore) getOIDCProvider(ctx context.Context, s logical.Storage,
return &provider, nil
}
// pathOIDCDeleteProvider is used to delete an assignment
// pathOIDCDeleteProvider is used to delete a provider
func (i *IdentityStore) pathOIDCDeleteProvider(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
return nil, req.Storage.Delete(ctx, providerPath+name)