2021-06-02 13:01:37 -05:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2021-06-02 13:01:37 -05:00
package managed_groups
import (
"context"
2023-03-15 11:40:40 -04:00
"encoding/json"
2021-06-02 13:01:37 -05:00
"fmt"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/auth"
2023-03-15 11:40:40 -04:00
"github.com/hashicorp/boundary/internal/auth/ldap"
ldapstore "github.com/hashicorp/boundary/internal/auth/ldap/store"
2021-06-02 13:01:37 -05:00
"github.com/hashicorp/boundary/internal/auth/oidc"
oidcstore "github.com/hashicorp/boundary/internal/auth/oidc/store"
2022-05-09 12:45:10 -07:00
requestauth "github.com/hashicorp/boundary/internal/daemon/controller/auth"
"github.com/hashicorp/boundary/internal/daemon/controller/common"
"github.com/hashicorp/boundary/internal/daemon/controller/handlers"
2021-06-02 13:01:37 -05:00
"github.com/hashicorp/boundary/internal/errors"
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
2024-01-03 14:35:54 -05:00
"github.com/hashicorp/boundary/internal/listtoken"
"github.com/hashicorp/boundary/internal/pagination"
2021-06-02 13:01:37 -05:00
"github.com/hashicorp/boundary/internal/perms"
"github.com/hashicorp/boundary/internal/requests"
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
2021-07-27 09:59:52 -07:00
"github.com/hashicorp/boundary/internal/types/subtypes"
2021-08-26 10:44:41 -04:00
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/managedgroups"
2021-06-02 13:01:37 -05:00
"github.com/hashicorp/go-bexpr"
2023-10-11 18:26:16 +00:00
"golang.org/x/exp/maps"
2021-06-02 13:01:37 -05:00
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/types/known/wrapperspb"
)
const (
// oidc field names
2023-03-15 11:40:40 -04:00
attrFilterField = "attributes.filter"
attrGroupNamesField = "attributes.group_names"
2022-04-12 16:09:40 -04:00
domain = "auth"
2021-06-02 13:01:37 -05:00
)
var (
oidcMaskManager handlers . MaskManager
2023-03-15 11:40:40 -04:00
ldapMaskManager handlers . MaskManager
2021-06-02 13:01:37 -05:00
// IdActions contains the set of actions that can be performed on
// individual resources
2023-11-15 19:55:46 -05:00
IdActions = map [ globals . Subtype ] action . ActionSet {
2023-10-31 13:44:17 +00:00
oidc . Subtype : action . NewActionSet (
2021-06-02 13:01:37 -05:00
action . NoOp ,
action . Read ,
action . Update ,
action . Delete ,
2023-10-31 13:44:17 +00:00
),
ldap . Subtype : action . NewActionSet (
2023-03-15 11:40:40 -04:00
action . NoOp ,
action . Read ,
action . Update ,
action . Delete ,
2023-10-31 13:44:17 +00:00
),
2021-06-02 13:01:37 -05:00
}
// CollectionActions contains the set of actions that can be performed on
// this collection
2023-10-31 13:44:17 +00:00
CollectionActions = action . NewActionSet (
2021-06-02 13:01:37 -05:00
action . Create ,
action . List ,
2023-10-31 13:44:17 +00:00
)
2021-06-02 13:01:37 -05:00
)
func init () {
var err error
2023-06-06 17:09:08 -04:00
if oidcMaskManager , err = handlers . NewMaskManager (
context . Background (),
handlers . MaskDestination { & oidcstore . ManagedGroup {}},
handlers . MaskSource { & pb . ManagedGroup {}, & pb . OidcManagedGroupAttributes {}},
); err != nil {
2021-06-02 13:01:37 -05:00
panic ( err )
}
2023-06-06 17:09:08 -04:00
if ldapMaskManager , err = handlers . NewMaskManager (
context . Background (),
handlers . MaskDestination { & ldapstore . ManagedGroup {}},
handlers . MaskSource { & pb . ManagedGroup {}, & pb . LdapManagedGroupAttributes {}},
); err != nil {
2023-03-15 11:40:40 -04:00
panic ( err )
}
2023-10-11 18:26:16 +00:00
// TODO: refactor to remove IdActions and CollectionActions package variables
action . RegisterResource ( resource . ManagedGroup , action . Union ( maps . Values ( IdActions ) ... ), CollectionActions )
2021-06-02 13:01:37 -05:00
}
// Service handles request as described by the pbs.ManagedGroupServiceServer interface.
type Service struct {
2022-08-30 14:22:10 -04:00
pbs . UnsafeManagedGroupServiceServer
2021-06-02 13:01:37 -05:00
2024-01-03 14:35:54 -05:00
oidcRepoFn common . OidcAuthRepoFactory
ldapRepoFn common . LdapAuthRepoFactory
maxPageSize uint
2021-06-02 13:01:37 -05:00
}
2022-08-30 14:22:10 -04:00
var _ pbs . ManagedGroupServiceServer = ( * Service )( nil )
2021-06-02 13:01:37 -05:00
// NewService returns a managed group service which handles managed group related requests to boundary.
2024-01-03 14:35:54 -05:00
func NewService ( ctx context . Context , oidcRepo common . OidcAuthRepoFactory , ldapRepo common . LdapAuthRepoFactory , maxPageSize uint ) ( Service , error ) {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.NewService"
2023-03-15 11:40:40 -04:00
switch {
case oidcRepo == nil :
return Service {}, errors . New ( ctx , errors . InvalidParameter , op , "missing oidc repository provided" )
case ldapRepo == nil :
return Service {}, errors . New ( ctx , errors . InvalidParameter , op , "missing ldap repository provided" )
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
if maxPageSize == 0 {
maxPageSize = uint ( globals . DefaultMaxPageSize )
}
return Service { oidcRepoFn : oidcRepo , ldapRepoFn : ldapRepo , maxPageSize : maxPageSize }, nil
2021-06-02 13:01:37 -05:00
}
// ListManagedGroups implements the interface pbs.ManagedGroupsServiceServer.
func ( s Service ) ListManagedGroups ( ctx context . Context , req * pbs . ListManagedGroupsRequest ) ( * pbs . ListManagedGroupsResponse , error ) {
2024-01-03 14:35:54 -05:00
const op = "managed_groups.(Service).ListManagedGroups"
2023-06-06 17:09:08 -04:00
if err := validateListRequest ( ctx , req ); err != nil {
2024-01-03 14:35:54 -05:00
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
_ , authResults := s . parentAndAuthResult ( ctx , req . GetAuthMethodId (), action . List )
if authResults . Error != nil {
return nil , authResults . Error
}
2024-01-03 14:35:54 -05:00
authMethodId := req . GetAuthMethodId ()
pageSize := int ( s . maxPageSize )
// Use the requested page size only if it is smaller than
// the configured max.
if req . GetPageSize () != 0 && uint ( req . GetPageSize ()) < s . maxPageSize {
pageSize = int ( req . GetPageSize ())
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
var filterItemFn func ( ctx context . Context , item auth . ManagedGroup ) ( bool , error )
switch {
case req . GetFilter () != "" :
// Only use a filter if we need to
filter , err := handlers . NewFilter ( ctx , req . GetFilter ())
if err != nil {
return nil , err
}
// TODO: replace the need for this function with some way to convert the `filter`
// to a domain type. This would allow filtering to happen in the domain, and we could
// remove this callback altogether.
filterItemFn = func ( ctx context . Context , item auth . ManagedGroup ) ( bool , error ) {
outputOpts , ok := newOutputOpts ( ctx , item , authMethodId , authResults )
if ! ok {
return false , nil
}
pbItem , err := toProto ( ctx , item , outputOpts ... )
if err != nil {
return false , err
}
filterable , err := subtypes . Filterable ( ctx , pbItem )
if err != nil {
return false , err
}
return filter . Match ( filterable ), nil
}
default :
filterItemFn = func ( ctx context . Context , item auth . ManagedGroup ) ( bool , error ) {
return true , nil
}
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
grantsHash , err := authResults . GrantsHash ( ctx )
2021-06-02 13:01:37 -05:00
if err != nil {
return nil , err
}
2024-01-03 14:35:54 -05:00
var listResp * pagination . ListResponse [ auth . ManagedGroup ]
var sortBy string
switch globals . ResourceInfoFromPrefix ( authMethodId ). Subtype {
case ldap . Subtype :
repo , err := s . ldapRepoFn ()
if err != nil {
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
if req . GetListToken () == "" {
sortBy = "created_time"
listResp , err = ldap . ListManagedGroups ( ctx , grantsHash , pageSize , filterItemFn , repo , authMethodId )
if err != nil {
return nil , err
}
} else {
listToken , err := handlers . ParseListToken ( ctx , req . GetListToken (), resource . ManagedGroup , grantsHash )
if err != nil {
return nil , err
}
switch st := listToken . Subtype .( type ) {
case * listtoken . PaginationToken :
sortBy = "created_time"
listResp , err = ldap . ListManagedGroupsPage ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
case * listtoken . StartRefreshToken :
sortBy = "updated_time"
listResp , err = ldap . ListManagedGroupsRefresh ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
case * listtoken . RefreshToken :
sortBy = "updated_time"
listResp , err = ldap . ListManagedGroupsRefreshPage ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
default :
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . InvalidArgument , "unexpected list token subtype: %T" , st )
}
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
case oidc . Subtype :
repo , err := s . oidcRepoFn ()
if err != nil {
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
if req . GetListToken () == "" {
sortBy = "created_time"
listResp , err = oidc . ListManagedGroups ( ctx , grantsHash , pageSize , filterItemFn , repo , authMethodId )
if err != nil {
return nil , err
}
} else {
listToken , err := handlers . ParseListToken ( ctx , req . GetListToken (), resource . ManagedGroup , grantsHash )
if err != nil {
return nil , err
}
switch st := listToken . Subtype .( type ) {
case * listtoken . PaginationToken :
sortBy = "created_time"
listResp , err = oidc . ListManagedGroupsPage ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
case * listtoken . StartRefreshToken :
sortBy = "updated_time"
listResp , err = oidc . ListManagedGroupsRefresh ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
case * listtoken . RefreshToken :
sortBy = "updated_time"
listResp , err = oidc . ListManagedGroupsRefreshPage ( ctx , grantsHash , pageSize , filterItemFn , listToken , repo , authMethodId )
if err != nil {
return nil , err
}
default :
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . InvalidArgument , "unexpected list token subtype: %T" , st )
}
}
default :
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . InvalidArgument , "unknown auth method type for id: %s" , authMethodId )
}
2021-06-02 13:01:37 -05:00
2024-01-03 14:35:54 -05:00
finalItems := make ([] * pb . ManagedGroup , 0 , len ( listResp . Items ))
for _ , item := range listResp . Items {
outputOpts , ok := newOutputOpts ( ctx , item , authMethodId , authResults )
if ! ok {
continue
}
pbItem , err := toProto ( ctx , item , outputOpts ... )
2021-06-02 13:01:37 -05:00
if err != nil {
2024-01-03 14:35:54 -05:00
continue
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
finalItems = append ( finalItems , pbItem )
}
respType := "delta"
if listResp . CompleteListing {
respType = "complete"
}
resp := & pbs . ListManagedGroupsResponse {
Items : finalItems ,
EstItemCount : uint32 ( listResp . EstimatedItemCount ),
RemovedIds : listResp . DeletedIds ,
ResponseType : respType ,
SortBy : sortBy ,
SortDir : "desc" ,
}
2021-06-02 13:01:37 -05:00
2024-01-03 14:35:54 -05:00
if listResp . ListToken != nil {
resp . ListToken , err = handlers . MarshalListToken ( ctx , listResp . ListToken , pbs . ResourceType_RESOURCE_TYPE_MANAGED_GROUP )
2022-04-08 16:09:52 -04:00
if err != nil {
return nil , err
}
2021-06-02 13:01:37 -05:00
}
2024-01-03 14:35:54 -05:00
return resp , nil
2021-06-02 13:01:37 -05:00
}
// GetManagedGroup implements the interface pbs.ManagedGroupServiceServer.
func ( s Service ) GetManagedGroup ( ctx context . Context , req * pbs . GetManagedGroupRequest ) ( * pbs . GetManagedGroupResponse , error ) {
const op = "managed_groups.(Service).GetManagedGroup"
2023-06-06 17:09:08 -04:00
if err := validateGetRequest ( ctx , req ); err != nil {
2021-06-02 13:01:37 -05:00
return nil , err
}
_ , authResults := s . parentAndAuthResult ( ctx , req . GetId (), action . Read )
if authResults . Error != nil {
return nil , authResults . Error
}
2021-06-02 13:05:10 -05:00
mg , memberIds , err := s . getFromRepo ( ctx , req . GetId ())
2021-06-02 13:01:37 -05:00
if err != nil {
return nil , err
}
outputFields , ok := requests . OutputFields ( ctx )
if ! ok {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . Internal , op , "no request context found" )
2021-06-02 13:01:37 -05:00
}
outputOpts := make ([] handlers . Option , 0 , 3 )
2023-01-06 17:27:19 -06:00
outputOpts = append ( outputOpts , handlers . WithOutputFields ( outputFields ))
2021-06-02 13:01:37 -05:00
if outputFields . Has ( globals . ScopeField ) {
outputOpts = append ( outputOpts , handlers . WithScope ( authResults . Scope ))
}
if outputFields . Has ( globals . AuthorizedActionsField ) {
2023-11-15 19:55:46 -05:00
outputOpts = append ( outputOpts , handlers . WithAuthorizedActions ( authResults . FetchActionSetForId ( ctx , mg . GetPublicId (), IdActions [ globals . ResourceInfoFromPrefix ( mg . GetPublicId ()). Subtype ]). Strings ()))
2021-06-02 13:01:37 -05:00
}
2021-06-02 13:05:10 -05:00
if outputFields . Has ( globals . MemberIdsField ) {
outputOpts = append ( outputOpts , handlers . WithMemberIds ( memberIds ))
}
2021-06-02 13:01:37 -05:00
item , err := toProto ( ctx , mg , outputOpts ... )
if err != nil {
return nil , err
}
return & pbs . GetManagedGroupResponse { Item : item }, nil
}
// CreateManagedGroup implements the interface pbs.ManagedGroupServiceServer.
func ( s Service ) CreateManagedGroup ( ctx context . Context , req * pbs . CreateManagedGroupRequest ) ( * pbs . CreateManagedGroupResponse , error ) {
const op = "managed_groups.(Service).CreateManagedGroup"
2023-06-06 17:09:08 -04:00
if err := validateCreateRequest ( ctx , req ); err != nil {
2021-06-02 13:01:37 -05:00
return nil , err
}
authMeth , authResults := s . parentAndAuthResult ( ctx , req . GetItem (). GetAuthMethodId (), action . Create )
if authResults . Error != nil {
return nil , authResults . Error
}
mg , err := s . createInRepo ( ctx , authMeth , req . GetItem ())
if err != nil {
return nil , err
}
outputFields , ok := requests . OutputFields ( ctx )
if ! ok {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . Internal , op , "no request context found" )
2021-06-02 13:01:37 -05:00
}
outputOpts := make ([] handlers . Option , 0 , 3 )
2023-01-06 17:27:19 -06:00
outputOpts = append ( outputOpts , handlers . WithOutputFields ( outputFields ))
2021-06-02 13:01:37 -05:00
if outputFields . Has ( globals . ScopeField ) {
outputOpts = append ( outputOpts , handlers . WithScope ( authResults . Scope ))
}
if outputFields . Has ( globals . AuthorizedActionsField ) {
2023-11-15 19:55:46 -05:00
outputOpts = append ( outputOpts , handlers . WithAuthorizedActions ( authResults . FetchActionSetForId ( ctx , mg . GetPublicId (), IdActions [ globals . ResourceInfoFromPrefix ( mg . GetPublicId ()). Subtype ]). Strings ()))
2021-06-02 13:01:37 -05:00
}
item , err := toProto ( ctx , mg , outputOpts ... )
if err != nil {
return nil , err
}
return & pbs . CreateManagedGroupResponse { Item : item , Uri : fmt . Sprintf ( "managed-groups/%s" , item . GetId ())}, nil
}
// UpdateManagedGroup implements the interface pbs.ManagedGroupServiceServer.
func ( s Service ) UpdateManagedGroup ( ctx context . Context , req * pbs . UpdateManagedGroupRequest ) ( * pbs . UpdateManagedGroupResponse , error ) {
const op = "managed_groups.(Service).UpdateManagedGroup"
2023-06-06 17:09:08 -04:00
if err := validateUpdateRequest ( ctx , req ); err != nil {
2021-06-02 13:01:37 -05:00
return nil , err
}
authMeth , authResults := s . parentAndAuthResult ( ctx , req . GetId (), action . Update )
if authResults . Error != nil {
return nil , authResults . Error
}
mg , err := s . updateInRepo ( ctx , authResults . Scope . GetId (), authMeth . GetPublicId (), req )
if err != nil {
return nil , err
}
outputFields , ok := requests . OutputFields ( ctx )
if ! ok {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . Internal , op , "no request context found" )
2021-06-02 13:01:37 -05:00
}
outputOpts := make ([] handlers . Option , 0 , 3 )
2023-01-06 17:27:19 -06:00
outputOpts = append ( outputOpts , handlers . WithOutputFields ( outputFields ))
2021-06-02 13:01:37 -05:00
if outputFields . Has ( globals . ScopeField ) {
outputOpts = append ( outputOpts , handlers . WithScope ( authResults . Scope ))
}
if outputFields . Has ( globals . AuthorizedActionsField ) {
2023-11-15 19:55:46 -05:00
outputOpts = append ( outputOpts , handlers . WithAuthorizedActions ( authResults . FetchActionSetForId ( ctx , mg . GetPublicId (), IdActions [ globals . ResourceInfoFromPrefix ( mg . GetPublicId ()). Subtype ]). Strings ()))
2021-06-02 13:01:37 -05:00
}
item , err := toProto ( ctx , mg , outputOpts ... )
if err != nil {
return nil , err
}
return & pbs . UpdateManagedGroupResponse { Item : item }, nil
}
// DeleteManagedGroup implements the interface pbs.ManagedGroupServiceServer.
func ( s Service ) DeleteManagedGroup ( ctx context . Context , req * pbs . DeleteManagedGroupRequest ) ( * pbs . DeleteManagedGroupResponse , error ) {
2023-06-06 17:09:08 -04:00
if err := validateDeleteRequest ( ctx , req ); err != nil {
2021-06-02 13:01:37 -05:00
return nil , err
}
_ , authResults := s . parentAndAuthResult ( ctx , req . GetId (), action . Delete )
if authResults . Error != nil {
return nil , authResults . Error
}
_ , err := s . deleteFromRepo ( ctx , authResults . Scope . GetId (), req . GetId ())
if err != nil {
return nil , err
}
return nil , nil
}
2021-06-02 13:05:10 -05:00
func ( s Service ) getFromRepo ( ctx context . Context , id string ) ( auth . ManagedGroup , [] string , error ) {
2021-06-02 13:01:37 -05:00
var out auth . ManagedGroup
2021-06-02 13:05:10 -05:00
var memberIds [] string
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( id ). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2021-06-02 13:01:37 -05:00
repo , err := s . oidcRepoFn ()
if err != nil {
2021-06-02 13:05:10 -05:00
return nil , nil , err
2021-06-02 13:01:37 -05:00
}
mg , err := repo . LookupManagedGroup ( ctx , id )
if err != nil {
if errors . IsNotFoundError ( err ) {
2021-06-02 13:05:10 -05:00
return nil , nil , handlers . NotFoundErrorf ( "ManagedGroup %q doesn't exist." , id )
}
return nil , nil , err
}
2024-11-15 10:27:20 -08:00
ids , err := repo . ListManagedGroupMembershipsByGroup ( ctx , mg . GetPublicId (), oidc . WithLimit ( - 1 ))
2021-06-02 13:05:10 -05:00
if err != nil {
return nil , nil , err
}
if len ( ids ) > 0 {
memberIds = make ([] string , len ( ids ))
for i , v := range ids {
memberIds [ i ] = v . MemberId
2021-06-02 13:01:37 -05:00
}
}
out = mg
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
repo , err := s . ldapRepoFn ()
if err != nil {
return nil , nil , err
}
mg , err := repo . LookupManagedGroup ( ctx , id )
if err != nil {
if errors . IsNotFoundError ( err ) {
return nil , nil , handlers . NotFoundErrorf ( "LDAP ManagedGroup %q doesn't exist." , id )
}
return nil , nil , err
}
2024-11-15 10:27:20 -08:00
ids , err := repo . ListManagedGroupMembershipsByGroup ( ctx , mg . GetPublicId (), ldap . WithLimit ( ctx , - 1 ))
2023-03-15 11:40:40 -04:00
if err != nil {
return nil , nil , err
}
if len ( ids ) > 0 {
memberIds = make ([] string , len ( ids ))
for i , v := range ids {
memberIds [ i ] = v . MemberId
}
}
out = mg
2021-06-02 13:01:37 -05:00
default :
2021-06-02 13:05:10 -05:00
return nil , nil , handlers . NotFoundErrorf ( "Unrecognized id." )
2021-06-02 13:01:37 -05:00
}
2021-06-02 13:05:10 -05:00
return out , memberIds , nil
2021-06-02 13:01:37 -05:00
}
func ( s Service ) createOidcInRepo ( ctx context . Context , am auth . AuthMethod , item * pb . ManagedGroup ) ( * oidc . ManagedGroup , error ) {
const op = "managed_groups.(Service).createOidcInRepo"
if item == nil {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . InvalidParameter , op , "missing item" )
2021-06-02 13:01:37 -05:00
}
var opts [] oidc . Option
if item . GetName () != nil {
opts = append ( opts , oidc . WithName ( item . GetName (). GetValue ()))
}
if item . GetDescription () != nil {
opts = append ( opts , oidc . WithDescription ( item . GetDescription (). GetValue ()))
}
2022-04-08 16:09:52 -04:00
attrs := item . GetOidcManagedGroupAttributes ()
2021-07-29 18:52:56 -06:00
mg , err := oidc . NewManagedGroup ( ctx , am . GetPublicId (), attrs . GetFilter (), opts ... )
2021-06-02 13:01:37 -05:00
if err != nil {
2023-03-15 11:40:40 -04:00
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to build managed group for creation: %v." , err )
2021-06-02 13:01:37 -05:00
}
repo , err := s . oidcRepoFn ()
if err != nil {
return nil , err
}
out , err := repo . CreateManagedGroup ( ctx , am . GetScopeId (), mg )
if err != nil {
2021-07-29 18:52:56 -06:00
return nil , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to create managed group" ))
2021-06-02 13:01:37 -05:00
}
if out == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to create managed group but no error returned from repository." )
}
return out , nil
}
2023-03-15 11:40:40 -04:00
func ( s Service ) createLdapInRepo ( ctx context . Context , am auth . AuthMethod , item * pb . ManagedGroup ) ( * ldap . ManagedGroup , error ) {
const op = "managed_groups.(Service).createLdapInRepo"
if item == nil {
return nil , errors . New ( ctx , errors . InvalidParameter , op , "missing item" )
}
var opts [] ldap . Option
if item . GetName () != nil {
opts = append ( opts , ldap . WithName ( ctx , item . GetName (). GetValue ()))
}
if item . GetDescription () != nil {
opts = append ( opts , ldap . WithDescription ( ctx , item . GetDescription (). GetValue ()))
}
attrs := item . GetLdapManagedGroupAttributes ()
mg , err := ldap . NewManagedGroup ( ctx , am . GetPublicId (), attrs . GetGroupNames (), opts ... )
if err != nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to build managed group for creation: %v." , err )
}
repo , err := s . ldapRepoFn ()
if err != nil {
return nil , err
}
out , err := repo . CreateManagedGroup ( ctx , am . GetScopeId (), mg )
if err != nil {
return nil , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to create managed group" ))
}
if out == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to create managed group but no error returned from repository." )
}
return out , nil
}
2021-06-02 13:01:37 -05:00
func ( s Service ) createInRepo ( ctx context . Context , am auth . AuthMethod , item * pb . ManagedGroup ) ( auth . ManagedGroup , error ) {
const op = "managed_groups.(Service).createInRepo"
if item == nil {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . InvalidParameter , op , "missing item" )
2021-06-02 13:01:37 -05:00
}
var out auth . ManagedGroup
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( am . GetPublicId ()). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2021-06-02 13:01:37 -05:00
am , err := s . createOidcInRepo ( ctx , am , item )
if err != nil {
2021-07-29 18:52:56 -06:00
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
if am == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to create managed group but no error returned from repository." )
}
out = am
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
am , err := s . createLdapInRepo ( ctx , am , item )
if err != nil {
return nil , errors . Wrap ( ctx , err , op )
}
if am == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to create ldap managed group but no error returned from repository." )
}
out = am
2021-06-02 13:01:37 -05:00
}
return out , nil
}
func ( s Service ) updateOidcInRepo ( ctx context . Context , scopeId , amId , id string , mask [] string , item * pb . ManagedGroup ) ( * oidc . ManagedGroup , error ) {
const op = "managed_groups.(Service).updateOidcInRepo"
if item == nil {
2021-07-29 18:52:56 -06:00
return nil , errors . New ( ctx , errors . InvalidParameter , op , "nil managed group." )
2021-06-02 13:01:37 -05:00
}
mg := oidc . AllocManagedGroup ()
mg . PublicId = id
if item . GetName () != nil {
mg . Name = item . GetName (). GetValue ()
}
if item . GetDescription () != nil {
mg . Description = item . GetDescription (). GetValue ()
}
2022-04-08 16:09:52 -04:00
// Set this regardless; it'll only take effect if the masks contain the value
mg . Filter = item . GetOidcManagedGroupAttributes (). GetFilter ()
2021-06-02 13:01:37 -05:00
version := item . GetVersion ()
dbMask := oidcMaskManager . Translate ( mask )
if len ( dbMask ) == 0 {
return nil , handlers . InvalidArgumentErrorf ( "No valid fields included in the update mask." , map [ string ] string { "update_mask" : "No valid fields provided in the update mask." })
}
repo , err := s . oidcRepoFn ()
if err != nil {
2021-07-29 18:52:56 -06:00
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
out , rowsUpdated , err := repo . UpdateManagedGroup ( ctx , scopeId , mg , version , dbMask )
if err != nil {
2021-07-29 18:52:56 -06:00
return nil , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to update managed group" ))
2021-06-02 13:01:37 -05:00
}
if rowsUpdated == 0 {
return nil , handlers . NotFoundErrorf ( "Managed Group %q doesn't exist or incorrect version provided." , id )
}
return out , nil
}
2023-03-15 11:40:40 -04:00
func ( s Service ) updateLdapInRepo ( ctx context . Context , scopeId , amId , id string , mask [] string , item * pb . ManagedGroup ) ( * ldap . ManagedGroup , error ) {
const op = "managed_groups.(Service).updateLdapInRepo"
if item == nil {
return nil , errors . New ( ctx , errors . InvalidParameter , op , "nil managed group." )
}
mg := ldap . AllocManagedGroup ()
mg . PublicId = id
if item . GetName () != nil {
mg . Name = item . GetName (). GetValue ()
}
if item . GetDescription () != nil {
mg . Description = item . GetDescription (). GetValue ()
}
// Set this regardless; it'll only take effect if the masks contain the value
encodedGroupNames , err := json . Marshal ( item . GetLdapManagedGroupAttributes (). GetGroupNames ())
if err != nil {
return nil , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to encode group names" ))
}
mg . GroupNames = string ( encodedGroupNames )
version := item . GetVersion ()
dbMask := ldapMaskManager . Translate ( mask )
if len ( dbMask ) == 0 {
return nil , handlers . InvalidArgumentErrorf ( "No valid fields included in the update mask." , map [ string ] string { "update_mask" : "No valid fields provided in the update mask." })
}
repo , err := s . ldapRepoFn ()
if err != nil {
return nil , errors . Wrap ( ctx , err , op )
}
out , rowsUpdated , err := repo . UpdateManagedGroup ( ctx , scopeId , mg , version , dbMask )
if err != nil {
return nil , errors . Wrap ( ctx , err , op , errors . WithMsg ( "unable to update managed group" ))
}
if rowsUpdated == 0 {
return nil , handlers . NotFoundErrorf ( "Managed Group %q doesn't exist or incorrect version provided." , id )
}
return out , nil
}
2021-06-02 13:01:37 -05:00
func ( s Service ) updateInRepo ( ctx context . Context , scopeId , authMethodId string , req * pbs . UpdateManagedGroupRequest ) ( auth . ManagedGroup , error ) {
const op = "managed_groups.(Service).updateInRepo"
var out auth . ManagedGroup
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( req . GetId ()). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2021-06-02 13:01:37 -05:00
mg , err := s . updateOidcInRepo ( ctx , scopeId , authMethodId , req . GetId (), req . GetUpdateMask (). GetPaths (), req . GetItem ())
if err != nil {
2021-07-29 18:52:56 -06:00
return nil , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
if mg == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to update managed group but no error returned from repository." )
}
out = mg
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
mg , err := s . updateLdapInRepo ( ctx , scopeId , authMethodId , req . GetId (), req . GetUpdateMask (). GetPaths (), req . GetItem ())
if err != nil {
return nil , errors . Wrap ( ctx , err , op )
}
if mg == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "Unable to update managed group but no error returned from repository." )
}
out = mg
2021-06-02 13:01:37 -05:00
}
return out , nil
}
func ( s Service ) deleteFromRepo ( ctx context . Context , scopeId , id string ) ( bool , error ) {
const op = "managed_groups.(Service).deleteFromRepo"
var rows int
var err error
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( id ). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2021-06-02 13:01:37 -05:00
repo , iErr := s . oidcRepoFn ()
if iErr != nil {
return false , iErr
}
rows , err = repo . DeleteManagedGroup ( ctx , scopeId , id )
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
repo , iErr := s . ldapRepoFn ()
if iErr != nil {
return false , iErr
}
rows , err = repo . DeleteManagedGroup ( ctx , scopeId , id )
2021-06-02 13:01:37 -05:00
}
if err != nil {
if errors . IsNotFoundError ( err ) {
return false , nil
}
2021-07-29 18:52:56 -06:00
return false , errors . Wrap ( ctx , err , op )
2021-06-02 13:01:37 -05:00
}
return rows > 0 , nil
}
2021-07-27 09:59:52 -07:00
func ( s Service ) parentAndAuthResult ( ctx context . Context , id string , a action . Type ) ( auth . AuthMethod , requestauth . VerifyResults ) {
const op = "managed_groups.(Service)."
res := requestauth . VerifyResults {}
2021-06-02 13:01:37 -05:00
oidcRepo , err := s . oidcRepoFn ()
if err != nil {
res . Error = err
return nil , res
}
2023-03-15 11:40:40 -04:00
ldapRepo , err := s . ldapRepoFn ()
if err != nil {
res . Error = err
return nil , res
}
2021-06-02 13:01:37 -05:00
var parentId string
2021-07-27 09:59:52 -07:00
opts := [] requestauth . Option { requestauth . WithType ( resource . ManagedGroup ), requestauth . WithAction ( a )}
2021-06-02 13:01:37 -05:00
switch a {
case action . List , action . Create :
parentId = id
default :
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( id ). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2023-03-15 11:40:40 -04:00
grp , err := oidcRepo . LookupManagedGroup ( ctx , id )
2021-06-02 13:01:37 -05:00
if err != nil {
res . Error = err
return nil , res
}
2023-03-15 11:40:40 -04:00
if grp == nil {
2021-06-02 13:01:37 -05:00
res . Error = handlers . NotFoundError ()
return nil , res
}
2023-03-15 11:40:40 -04:00
parentId = grp . GetAuthMethodId ()
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
grp , err := ldapRepo . LookupManagedGroup ( ctx , id )
if err != nil {
res . Error = err
return nil , res
}
if grp == nil {
res . Error = handlers . NotFoundError ()
return nil , res
}
parentId = grp . GetAuthMethodId ()
2021-07-27 09:59:52 -07:00
default :
2021-07-29 18:52:56 -06:00
res . Error = errors . New ( ctx , errors . InvalidPublicId , op , "unrecognized managed group subtype" )
2021-07-27 09:59:52 -07:00
return nil , res
2021-06-02 13:01:37 -05:00
}
2021-07-27 09:59:52 -07:00
opts = append ( opts , requestauth . WithId ( id ))
2021-06-02 13:01:37 -05:00
}
var authMeth auth . AuthMethod
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( parentId ). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
2021-06-02 13:01:37 -05:00
am , err := oidcRepo . LookupAuthMethod ( ctx , parentId )
if err != nil {
res . Error = err
return nil , res
}
if am == nil {
res . Error = handlers . NotFoundError ()
return nil , res
}
authMeth = am
2021-07-27 09:59:52 -07:00
opts = append ( opts , requestauth . WithScopeId ( am . GetScopeId ()))
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
2023-03-15 11:40:40 -04:00
am , err := ldapRepo . LookupAuthMethod ( ctx , parentId )
if err != nil {
res . Error = err
return nil , res
}
if am == nil {
res . Error = handlers . NotFoundError ()
return nil , res
}
authMeth = am
opts = append ( opts , requestauth . WithScopeId ( am . GetScopeId ()))
2021-07-27 09:59:52 -07:00
default :
2021-07-29 18:52:56 -06:00
res . Error = errors . New ( ctx , errors . InvalidPublicId , op , "unrecognized auth method subtype" )
2021-07-27 09:59:52 -07:00
return nil , res
2021-06-02 13:01:37 -05:00
}
2021-07-27 09:59:52 -07:00
opts = append ( opts , requestauth . WithPin ( parentId ))
return authMeth , requestauth . Verify ( ctx , opts ... )
2021-06-02 13:01:37 -05:00
}
func toProto ( ctx context . Context , in auth . ManagedGroup , opt ... handlers . Option ) ( * pb . ManagedGroup , error ) {
opts := handlers . GetOpts ( opt ... )
if opts . WithOutputFields == nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "output fields not found when building managed group proto" )
}
outputFields := * opts . WithOutputFields
out := pb . ManagedGroup {}
if outputFields . Has ( globals . IdField ) {
out . Id = in . GetPublicId ()
}
if outputFields . Has ( globals . AuthMethodIdField ) {
out . AuthMethodId = in . GetAuthMethodId ()
}
if outputFields . Has ( globals . DescriptionField ) && in . GetDescription () != "" {
out . Description = & wrapperspb . StringValue { Value : in . GetDescription ()}
}
if outputFields . Has ( globals . NameField ) && in . GetName () != "" {
out . Name = & wrapperspb . StringValue { Value : in . GetName ()}
}
if outputFields . Has ( globals . CreatedTimeField ) {
out . CreatedTime = in . GetCreateTime (). GetTimestamp ()
}
if outputFields . Has ( globals . UpdatedTimeField ) {
out . UpdatedTime = in . GetUpdateTime (). GetTimestamp ()
}
if outputFields . Has ( globals . VersionField ) {
out . Version = in . GetVersion ()
}
if outputFields . Has ( globals . ScopeField ) {
out . Scope = opts . WithScope
}
if outputFields . Has ( globals . AuthorizedActionsField ) {
out . AuthorizedActions = opts . WithAuthorizedActions
}
2021-06-02 13:05:10 -05:00
if outputFields . Has ( globals . MemberIdsField ) {
out . MemberIds = opts . WithMemberIds
}
2021-06-02 13:01:37 -05:00
switch i := in .( type ) {
case * oidc . ManagedGroup :
if outputFields . Has ( globals . TypeField ) {
2023-11-02 16:03:47 -04:00
out . Type = oidc . Subtype . String ()
2021-06-02 13:01:37 -05:00
}
if ! outputFields . Has ( globals . AttributesField ) {
break
}
attrs := & pb . OidcManagedGroupAttributes {
Filter : i . GetFilter (),
}
2022-04-08 16:09:52 -04:00
out . Attrs = & pb . ManagedGroup_OidcManagedGroupAttributes {
OidcManagedGroupAttributes : attrs ,
2021-06-02 13:01:37 -05:00
}
2023-03-15 11:40:40 -04:00
case * ldap . ManagedGroup :
if outputFields . Has ( globals . TypeField ) {
2023-11-02 16:03:47 -04:00
out . Type = ldap . Subtype . String ()
2023-03-15 11:40:40 -04:00
}
if ! outputFields . Has ( globals . AttributesField ) {
break
}
var grpNames [] string
if err := json . Unmarshal ([] byte ( i . GetGroupNames ()), & grpNames ); err != nil {
return nil , handlers . ApiErrorWithCodeAndMessage ( codes . Internal , "unable to unmarshal group names" )
}
attrs := & pb . LdapManagedGroupAttributes {
GroupNames : grpNames ,
}
out . Attrs = & pb . ManagedGroup_LdapManagedGroupAttributes {
LdapManagedGroupAttributes : attrs ,
}
2021-06-02 13:01:37 -05:00
}
return & out , nil
}
// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce
// requirements on the structure of the request. They verify that:
2022-08-25 09:12:24 -07:00
// - The path passed in is correctly formatted
// - All required parameters are set
// - There are no conflicting parameters provided
2023-06-06 17:09:08 -04:00
func validateGetRequest ( ctx context . Context , req * pbs . GetManagedGroupRequest ) error {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.validateGetRequest"
if req == nil {
2023-06-06 17:09:08 -04:00
return errors . New ( ctx , errors . InvalidParameter , op , "nil request" )
2021-06-02 13:01:37 -05:00
}
2023-03-15 11:40:40 -04:00
return handlers . ValidateGetRequest ( handlers . NoopValidatorFn , req , globals . OidcManagedGroupPrefix , globals . LdapManagedGroupPrefix )
2021-06-02 13:01:37 -05:00
}
2023-06-06 17:09:08 -04:00
func validateCreateRequest ( ctx context . Context , req * pbs . CreateManagedGroupRequest ) error {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.validateCreateRequest"
if req == nil {
2023-06-06 17:09:08 -04:00
return errors . New ( ctx , errors . InvalidParameter , op , "nil request" )
2021-06-02 13:01:37 -05:00
}
return handlers . ValidateCreateRequest ( req . GetItem (), func () map [ string ] string {
badFields := map [ string ] string {}
if req . GetItem (). GetAuthMethodId () == "" {
badFields [ globals . AuthMethodIdField ] = "This field is required."
}
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( req . GetItem (). GetAuthMethodId ()). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
if req . GetItem (). GetType () != "" && req . GetItem (). GetType () != oidc . Subtype . String () {
2021-06-02 13:01:37 -05:00
badFields [ globals . TypeField ] = "Doesn't match the parent resource's type."
}
2022-04-08 16:09:52 -04:00
attrs := req . GetItem (). GetOidcManagedGroupAttributes ()
if attrs == nil {
badFields [ globals . AttributesField ] = "Attribute fields is required."
2021-06-02 13:01:37 -05:00
} else {
2022-08-24 15:01:54 -07:00
if attrs . Filter == "" {
badFields [ attrFilterField ] = "This field is required."
} else {
if _ , err := bexpr . CreateEvaluator ( attrs . Filter ); err != nil {
badFields [ attrFilterField ] = fmt . Sprintf ( "Error evaluating submitted filter expression: %v." , err )
}
2021-06-02 13:01:37 -05:00
}
}
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
if req . GetItem (). GetType () != "" && req . GetItem (). GetType () != ldap . Subtype . String () {
2023-03-15 11:40:40 -04:00
badFields [ globals . TypeField ] = "Doesn't match the parent resource's type."
}
attrs := req . GetItem (). GetLdapManagedGroupAttributes ()
if attrs == nil {
badFields [ globals . AttributesField ] = "Attribute fields is required."
} else {
if len ( attrs . GroupNames ) == 0 {
badFields [ attrGroupNamesField ] = "This field is required."
}
}
2021-06-02 13:01:37 -05:00
default :
badFields [ globals . AuthMethodIdField ] = "Unknown auth method type from ID."
}
return badFields
})
}
2023-06-06 17:09:08 -04:00
func validateUpdateRequest ( ctx context . Context , req * pbs . UpdateManagedGroupRequest ) error {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.validateUpdateRequest"
if req == nil {
2023-06-06 17:09:08 -04:00
return errors . New ( ctx , errors . InvalidParameter , op , "nil request" )
2021-06-02 13:01:37 -05:00
}
return handlers . ValidateUpdateRequest ( req , req . GetItem (), func () map [ string ] string {
badFields := map [ string ] string {}
2023-11-15 19:55:46 -05:00
switch globals . ResourceInfoFromPrefix ( req . GetId ()). Subtype {
2023-11-02 16:03:47 -04:00
case oidc . Subtype :
if req . GetItem (). GetType () != "" && req . GetItem (). GetType () != oidc . Subtype . String () {
2021-06-02 13:01:37 -05:00
badFields [ globals . TypeField ] = "Cannot modify the resource type."
}
2022-04-08 16:09:52 -04:00
attrs := req . GetItem (). GetOidcManagedGroupAttributes ()
2021-06-02 13:01:37 -05:00
if handlers . MaskContains ( req . GetUpdateMask (). GetPaths (), attrFilterField ) {
2022-06-19 10:55:37 -04:00
switch {
case attrs == nil :
badFields [ "attributes" ] = "Attributes field not supplied request"
default :
if attrs . Filter == "" {
badFields [ attrFilterField ] = "Field cannot be empty."
} else {
if _ , err := bexpr . CreateEvaluator ( attrs . Filter ); err != nil {
badFields [ attrFilterField ] = fmt . Sprintf ( "Error evaluating submitted filter expression: %v." , err )
}
2021-06-02 13:01:37 -05:00
}
}
}
2023-11-02 16:03:47 -04:00
case ldap . Subtype :
if req . GetItem (). GetType () != "" && req . GetItem (). GetType () != ldap . Subtype . String () {
2023-03-15 11:40:40 -04:00
badFields [ globals . TypeField ] = "Cannot modify the resource type."
}
attrs := req . GetItem (). GetLdapManagedGroupAttributes ()
if handlers . MaskContains ( req . GetUpdateMask (). GetPaths (), attrGroupNamesField ) {
if len ( attrs . GroupNames ) == 0 {
badFields [ attrFilterField ] = "Field cannot be empty."
}
}
2021-07-27 09:59:52 -07:00
default :
badFields [ globals . IdField ] = "Unrecognized resource type."
2021-06-02 13:01:37 -05:00
}
return badFields
2023-03-15 11:40:40 -04:00
}, globals . OidcManagedGroupPrefix , globals . LdapManagedGroupPrefix )
2021-06-02 13:01:37 -05:00
}
2023-06-06 17:09:08 -04:00
func validateDeleteRequest ( ctx context . Context , req * pbs . DeleteManagedGroupRequest ) error {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.validateDeleteRequest"
if req == nil {
2023-06-06 17:09:08 -04:00
return errors . New ( ctx , errors . InvalidParameter , op , "nil request" )
2021-06-02 13:01:37 -05:00
}
2023-03-15 11:40:40 -04:00
return handlers . ValidateDeleteRequest ( handlers . NoopValidatorFn , req , globals . OidcManagedGroupPrefix , globals . LdapManagedGroupPrefix )
2021-06-02 13:01:37 -05:00
}
2023-06-06 17:09:08 -04:00
func validateListRequest ( ctx context . Context , req * pbs . ListManagedGroupsRequest ) error {
2021-06-02 13:01:37 -05:00
const op = "managed_groups.validateListRequest"
if req == nil {
2023-06-06 17:09:08 -04:00
return errors . New ( ctx , errors . InvalidParameter , op , "nil request" )
2021-06-02 13:01:37 -05:00
}
badFields := map [ string ] string {}
2023-03-15 11:40:40 -04:00
if ! handlers . ValidId ( handlers . Id ( req . GetAuthMethodId ()), globals . OidcAuthMethodPrefix , globals . LdapAuthMethodPrefix ) {
2021-06-02 13:01:37 -05:00
badFields [ globals . AuthMethodIdField ] = "Invalid formatted identifier."
}
2023-06-06 17:09:08 -04:00
if _ , err := handlers . NewFilter ( ctx , req . GetFilter ()); err != nil {
2021-06-02 13:01:37 -05:00
badFields [ globals . FilterField ] = fmt . Sprintf ( "This field could not be parsed. %v" , err )
}
if len ( badFields ) > 0 {
return handlers . InvalidArgumentErrorf ( "Error in provided request." , badFields )
}
return nil
}
2024-01-03 14:35:54 -05:00
func newOutputOpts ( ctx context . Context , item auth . ManagedGroup , authMethodId string , authResults requestauth . VerifyResults ) ([] handlers . Option , bool ) {
res := perms . Resource {
2025-01-24 10:23:33 -08:00
ScopeId : authResults . Scope . Id ,
ParentScopeId : authResults . Scope . ParentScopeId ,
Type : resource . ManagedGroup ,
Pin : authMethodId ,
2024-01-03 14:35:54 -05:00
}
res . Id = item . GetPublicId ()
authorizedActions := authResults . FetchActionSetForId ( ctx , item . GetPublicId (), IdActions [ globals . ResourceInfoFromPrefix ( item . GetPublicId ()). Subtype ], requestauth . WithResource ( & res )). Strings ()
if len ( authorizedActions ) == 0 {
return nil , false
}
outputFields := authResults . FetchOutputFields ( res , action . List ). SelfOrDefaults ( authResults . UserId )
outputOpts := make ([] handlers . Option , 0 , 3 )
outputOpts = append ( outputOpts , handlers . WithOutputFields ( outputFields ))
if outputFields . Has ( globals . ScopeField ) {
outputOpts = append ( outputOpts , handlers . WithScope ( authResults . Scope ))
}
if outputFields . Has ( globals . AuthorizedActionsField ) {
outputOpts = append ( outputOpts , handlers . WithAuthorizedActions ( authorizedActions ))
}
return outputOpts , true
}