// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 package vault import ( "context" "fmt" "strings" "github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" ) func lookupPaths(i *IdentityStore) []*framework.Path { return []*framework.Path{ { Pattern: "lookup/entity$", DisplayAttrs: &framework.DisplayAttributes{ OperationPrefix: "entity", OperationVerb: "look-up", }, Fields: map[string]*framework.FieldSchema{ "name": { Type: framework.TypeString, Description: "Name of the entity.", }, "id": { Type: framework.TypeString, Description: "ID of the entity.", }, "alias_id": { Type: framework.TypeString, Description: "ID of the alias.", }, "alias_name": { Type: framework.TypeString, Description: "Name of the alias. This should be supplied in conjunction with 'alias_mount_accessor'.", }, "alias_mount_accessor": { Type: framework.TypeString, Description: "Accessor of the mount to which the alias belongs to. This should be supplied in conjunction with 'alias_name'.", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ logical.UpdateOperation: i.pathLookupEntityUpdate(), }, HelpSynopsis: strings.TrimSpace(lookupHelp["lookup-entity"][0]), HelpDescription: strings.TrimSpace(lookupHelp["lookup-entity"][1]), }, { Pattern: "lookup/group$", DisplayAttrs: &framework.DisplayAttributes{ OperationPrefix: "group", OperationVerb: "look-up", }, Fields: map[string]*framework.FieldSchema{ "name": { Type: framework.TypeString, Description: "Name of the group.", }, "id": { Type: framework.TypeString, Description: "ID of the group.", }, "alias_id": { Type: framework.TypeString, Description: "ID of the alias.", }, "alias_name": { Type: framework.TypeString, Description: "Name of the alias. This should be supplied in conjunction with 'alias_mount_accessor'.", }, "alias_mount_accessor": { Type: framework.TypeString, Description: "Accessor of the mount to which the alias belongs to. This should be supplied in conjunction with 'alias_name'.", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ logical.UpdateOperation: i.pathLookupGroupUpdate(), }, HelpSynopsis: strings.TrimSpace(lookupHelp["lookup-group"][0]), HelpDescription: strings.TrimSpace(lookupHelp["lookup-group"][1]), }, } } func (i *IdentityStore) pathLookupEntityUpdate() framework.OperationFunc { return func(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { var entity *identity.Entity var err error inputCount := 0 id := "" idRaw, ok := d.GetOk("id") if ok { inputCount++ id = idRaw.(string) } name := "" nameRaw, ok := d.GetOk("name") if ok { inputCount++ name = nameRaw.(string) } aliasID := "" aliasIDRaw, ok := d.GetOk("alias_id") if ok { inputCount++ aliasID = aliasIDRaw.(string) } aliasName := "" aliasNameRaw, ok := d.GetOk("alias_name") if ok { inputCount++ aliasName = aliasNameRaw.(string) } aliasMountAccessor := "" aliasMountAccessorRaw, ok := d.GetOk("alias_mount_accessor") if ok { inputCount++ aliasMountAccessor = aliasMountAccessorRaw.(string) } switch { case inputCount == 0: return logical.ErrorResponse(fmt.Sprintf("query parameter not supplied")), nil case inputCount != 1: switch { case inputCount == 2 && aliasName != "" && aliasMountAccessor != "": default: return logical.ErrorResponse(fmt.Sprintf("query parameter conflict; please supply distinct set of query parameters")), nil } case inputCount == 1: switch { case aliasName != "" || aliasMountAccessor != "": return logical.ErrorResponse(fmt.Sprintf("both 'alias_name' and 'alias_mount_accessor' needs to be set")), nil } } switch { case id != "": entity, err = i.MemDBEntityByID(id, false) if err != nil { return nil, err } case name != "": entity, err = i.MemDBEntityByName(ctx, name, false) if err != nil { return nil, err } case aliasID != "": alias, err := i.MemDBAliasByID(aliasID, false, false) if err != nil { return nil, err } if alias == nil { break } entity, err = i.MemDBEntityByAliasID(alias.ID, false) if err != nil { return nil, err } case aliasName != "" && aliasMountAccessor != "": alias, err := i.MemDBAliasByFactors(aliasMountAccessor, aliasName, false, false) if err != nil { return nil, err } if alias == nil { break } entity, err = i.MemDBEntityByAliasID(alias.ID, false) if err != nil { return nil, err } } if entity == nil { return nil, nil } return i.handleEntityReadCommon(ctx, entity) } } func (i *IdentityStore) pathLookupGroupUpdate() framework.OperationFunc { return func(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { var group *identity.Group var err error inputCount := 0 id := "" idRaw, ok := d.GetOk("id") if ok { inputCount++ id = idRaw.(string) } name := "" nameRaw, ok := d.GetOk("name") if ok { inputCount++ name = nameRaw.(string) } aliasID := "" aliasIDRaw, ok := d.GetOk("alias_id") if ok { inputCount++ aliasID = aliasIDRaw.(string) } aliasName := "" aliasNameRaw, ok := d.GetOk("alias_name") if ok { inputCount++ aliasName = aliasNameRaw.(string) } aliasMountAccessor := "" aliasMountAccessorRaw, ok := d.GetOk("alias_mount_accessor") if ok { inputCount++ aliasMountAccessor = aliasMountAccessorRaw.(string) } switch { case inputCount == 0: return logical.ErrorResponse(fmt.Sprintf("query parameter not supplied")), nil case inputCount != 1: switch { case inputCount == 2 && aliasName != "" && aliasMountAccessor != "": default: return logical.ErrorResponse(fmt.Sprintf("query parameter conflict; please supply distinct set of query parameters")), nil } case inputCount == 1: switch { case aliasName != "" || aliasMountAccessor != "": return logical.ErrorResponse(fmt.Sprintf("both 'alias_name' and 'alias_mount_accessor' needs to be set")), nil } } switch { case id != "": group, err = i.MemDBGroupByID(id, false) if err != nil { return nil, err } case name != "": group, err = i.MemDBGroupByName(ctx, name, false) if err != nil { return nil, err } case aliasID != "": alias, err := i.MemDBAliasByID(aliasID, false, true) if err != nil { return nil, err } if alias == nil { break } group, err = i.MemDBGroupByAliasID(alias.ID, false) if err != nil { return nil, err } case aliasName != "" && aliasMountAccessor != "": alias, err := i.MemDBAliasByFactors(aliasMountAccessor, aliasName, false, true) if err != nil { return nil, err } if alias == nil { break } group, err = i.MemDBGroupByAliasID(alias.ID, false) if err != nil { return nil, err } } if group == nil { return nil, nil } return i.handleGroupReadCommon(ctx, group) } } var lookupHelp = map[string][2]string{ "lookup-entity": { "Query entities based on various properties.", `Distinct query parameters to be set: - 'id' To query the entity by its ID. - 'name' To query the entity by its name. - 'alias_id' To query the entity by the ID of any of its aliases. - 'alias_name' and 'alias_mount_accessor' To query the entity by the unique factors that represent an alias; the name and the mount accessor. `, }, "lookup-group": { "Query groups based on various properties.", `Distinct query parameters to be set: - 'id' To query the group by its ID. - 'name' To query the group by its name. - 'alias_id' To query the group by the ID of any of its aliases. - 'alias_name' and 'alias_mount_accessor' To query the group by the unique factors that represent an alias; the name and the mount accessor. `, }, }