github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/client/accesslist/accesslist.go (about)

     1  // Copyright 2023 Gravitational, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package accesslist
    16  
    17  import (
    18  	"context"
    19  	"time"
    20  
    21  	"github.com/gravitational/trace"
    22  
    23  	accesslistv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1"
    24  	"github.com/gravitational/teleport/api/types/accesslist"
    25  	conv "github.com/gravitational/teleport/api/types/accesslist/convert/v1"
    26  )
    27  
    28  // Client is an access list client that conforms to the following lib/services interfaces:
    29  // * services.AccessLists
    30  type Client struct {
    31  	grpcClient accesslistv1.AccessListServiceClient
    32  }
    33  
    34  // NewClient creates a new Access List client.
    35  func NewClient(grpcClient accesslistv1.AccessListServiceClient) *Client {
    36  	return &Client{
    37  		grpcClient: grpcClient,
    38  	}
    39  }
    40  
    41  // GetAccessLists returns a list of all access lists.
    42  func (c *Client) GetAccessLists(ctx context.Context) ([]*accesslist.AccessList, error) {
    43  	resp, err := c.grpcClient.GetAccessLists(ctx, &accesslistv1.GetAccessListsRequest{})
    44  	if err != nil {
    45  		return nil, trace.Wrap(err)
    46  	}
    47  
    48  	accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
    49  	for i, accessList := range resp.AccessLists {
    50  		var err error
    51  		accessLists[i], err = conv.FromProto(accessList)
    52  		if err != nil {
    53  			return nil, trace.Wrap(err)
    54  		}
    55  	}
    56  
    57  	return accessLists, nil
    58  }
    59  
    60  // ListAccessLists returns a paginated list of access lists.
    61  func (c *Client) ListAccessLists(ctx context.Context, pageSize int, nextToken string) ([]*accesslist.AccessList, string, error) {
    62  	resp, err := c.grpcClient.ListAccessLists(ctx, &accesslistv1.ListAccessListsRequest{
    63  		PageSize:  int32(pageSize),
    64  		NextToken: nextToken,
    65  	})
    66  	if err != nil {
    67  		return nil, "", trace.Wrap(err)
    68  	}
    69  
    70  	accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
    71  	for i, accessList := range resp.AccessLists {
    72  		var err error
    73  		accessLists[i], err = conv.FromProto(accessList)
    74  		if err != nil {
    75  			return nil, "", trace.Wrap(err)
    76  		}
    77  	}
    78  
    79  	return accessLists, resp.GetNextToken(), nil
    80  }
    81  
    82  // GetAccessList returns the specified access list resource.
    83  func (c *Client) GetAccessList(ctx context.Context, name string) (*accesslist.AccessList, error) {
    84  	resp, err := c.grpcClient.GetAccessList(ctx, &accesslistv1.GetAccessListRequest{
    85  		Name: name,
    86  	})
    87  	if err != nil {
    88  		return nil, trace.Wrap(err)
    89  	}
    90  
    91  	accessList, err := conv.FromProto(resp, conv.WithOwnersIneligibleStatusField(resp.GetSpec().GetOwners()))
    92  	return accessList, trace.Wrap(err)
    93  }
    94  
    95  // GetAccessListsToReview returns access lists that the user needs to review.
    96  func (c *Client) GetAccessListsToReview(ctx context.Context) ([]*accesslist.AccessList, error) {
    97  	resp, err := c.grpcClient.GetAccessListsToReview(ctx, &accesslistv1.GetAccessListsToReviewRequest{})
    98  	if err != nil {
    99  		return nil, trace.Wrap(err)
   100  	}
   101  
   102  	accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
   103  	for i, accessList := range resp.AccessLists {
   104  		var err error
   105  		accessLists[i], err = conv.FromProto(accessList)
   106  		if err != nil {
   107  			return nil, trace.Wrap(err)
   108  		}
   109  	}
   110  
   111  	return accessLists, nil
   112  }
   113  
   114  // UpsertAccessList creates or updates an access list resource.
   115  func (c *Client) UpsertAccessList(ctx context.Context, accessList *accesslist.AccessList) (*accesslist.AccessList, error) {
   116  	resp, err := c.grpcClient.UpsertAccessList(ctx, &accesslistv1.UpsertAccessListRequest{
   117  		AccessList: conv.ToProto(accessList),
   118  	})
   119  	if err != nil {
   120  		return nil, trace.Wrap(err)
   121  	}
   122  	responseAccessList, err := conv.FromProto(resp)
   123  	return responseAccessList, trace.Wrap(err)
   124  }
   125  
   126  // UpdateAccessList updates an access list resource.
   127  func (c *Client) UpdateAccessList(ctx context.Context, accessList *accesslist.AccessList) (*accesslist.AccessList, error) {
   128  	resp, err := c.grpcClient.UpdateAccessList(ctx, &accesslistv1.UpdateAccessListRequest{
   129  		AccessList: conv.ToProto(accessList),
   130  	})
   131  	if err != nil {
   132  		return nil, trace.Wrap(err)
   133  	}
   134  	responseAccessList, err := conv.FromProto(resp)
   135  	return responseAccessList, trace.Wrap(err)
   136  }
   137  
   138  // DeleteAccessList removes the specified access list resource.
   139  func (c *Client) DeleteAccessList(ctx context.Context, name string) error {
   140  	_, err := c.grpcClient.DeleteAccessList(ctx, &accesslistv1.DeleteAccessListRequest{
   141  		Name: name,
   142  	})
   143  	return trace.Wrap(err)
   144  }
   145  
   146  // DeleteAllAccessLists removes all access lists.
   147  func (c *Client) DeleteAllAccessLists(ctx context.Context) error {
   148  	return trace.NotImplemented("DeleteAllAccessLists not supported in the gRPC client")
   149  }
   150  
   151  // CountAccessListMembers will count all access list members.
   152  func (c *Client) CountAccessListMembers(ctx context.Context, accessListName string) (uint32, error) {
   153  	resp, err := c.grpcClient.CountAccessListMembers(ctx, &accesslistv1.CountAccessListMembersRequest{
   154  		AccessListName: accessListName,
   155  	})
   156  	if err != nil {
   157  		return 0, trace.Wrap(err)
   158  	}
   159  
   160  	return resp.Count, nil
   161  }
   162  
   163  // ListAccessListMembers returns a paginated list of all access list members for an access list.
   164  func (c *Client) ListAccessListMembers(ctx context.Context, accessList string, pageSize int, pageToken string) (members []*accesslist.AccessListMember, nextToken string, err error) {
   165  	resp, err := c.grpcClient.ListAccessListMembers(ctx, &accesslistv1.ListAccessListMembersRequest{
   166  		PageSize:   int32(pageSize),
   167  		PageToken:  pageToken,
   168  		AccessList: accessList,
   169  	})
   170  	if err != nil {
   171  		return nil, "", trace.Wrap(err)
   172  	}
   173  
   174  	members = make([]*accesslist.AccessListMember, len(resp.Members))
   175  	for i, member := range resp.Members {
   176  		var err error
   177  		members[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
   178  		if err != nil {
   179  			return nil, "", trace.Wrap(err)
   180  		}
   181  	}
   182  
   183  	return members, resp.GetNextPageToken(), nil
   184  }
   185  
   186  // ListAllAccessListMembers returns a paginated list of all access list members for all access lists.
   187  func (c *Client) ListAllAccessListMembers(ctx context.Context, pageSize int, pageToken string) (members []*accesslist.AccessListMember, nextToken string, err error) {
   188  	resp, err := c.grpcClient.ListAllAccessListMembers(ctx, &accesslistv1.ListAllAccessListMembersRequest{
   189  		PageSize:  int32(pageSize),
   190  		PageToken: pageToken,
   191  	})
   192  	if err != nil {
   193  		return nil, "", trace.Wrap(err)
   194  	}
   195  
   196  	members = make([]*accesslist.AccessListMember, len(resp.Members))
   197  	for i, member := range resp.Members {
   198  		var err error
   199  		members[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
   200  		if err != nil {
   201  			return nil, "", trace.Wrap(err)
   202  		}
   203  	}
   204  
   205  	return members, resp.GetNextPageToken(), nil
   206  }
   207  
   208  // GetAccessListMember returns the specified access list member resource.
   209  func (c *Client) GetAccessListMember(ctx context.Context, accessList string, memberName string) (*accesslist.AccessListMember, error) {
   210  	resp, err := c.grpcClient.GetAccessListMember(ctx, &accesslistv1.GetAccessListMemberRequest{
   211  		AccessList: accessList,
   212  		MemberName: memberName,
   213  	})
   214  	if err != nil {
   215  		return nil, trace.Wrap(err)
   216  	}
   217  
   218  	member, err := conv.FromMemberProto(resp, conv.WithMemberIneligibleStatusField(resp))
   219  	return member, trace.Wrap(err)
   220  }
   221  
   222  // UpsertAccessListMember creates or updates an access list member resource.
   223  func (c *Client) UpsertAccessListMember(ctx context.Context, member *accesslist.AccessListMember) (*accesslist.AccessListMember, error) {
   224  	resp, err := c.grpcClient.UpsertAccessListMember(ctx, &accesslistv1.UpsertAccessListMemberRequest{
   225  		Member: conv.ToMemberProto(member),
   226  	})
   227  	if err != nil {
   228  		return nil, trace.Wrap(err)
   229  	}
   230  	responseMember, err := conv.FromMemberProto(resp)
   231  	return responseMember, trace.Wrap(err)
   232  }
   233  
   234  // UpdateAccessListMember updates an access list member resource using a conditional update.
   235  func (c *Client) UpdateAccessListMember(ctx context.Context, member *accesslist.AccessListMember) (*accesslist.AccessListMember, error) {
   236  	resp, err := c.grpcClient.UpdateAccessListMember(ctx, &accesslistv1.UpdateAccessListMemberRequest{
   237  		Member: conv.ToMemberProto(member),
   238  	})
   239  	if err != nil {
   240  		return nil, trace.Wrap(err)
   241  	}
   242  	responseMember, err := conv.FromMemberProto(resp)
   243  	return responseMember, trace.Wrap(err)
   244  }
   245  
   246  // DeleteAccessListMember hard deletes the specified access list member resource.
   247  func (c *Client) DeleteAccessListMember(ctx context.Context, accessList string, memberName string) error {
   248  	_, err := c.grpcClient.DeleteAccessListMember(ctx, &accesslistv1.DeleteAccessListMemberRequest{
   249  		AccessList: accessList,
   250  		MemberName: memberName,
   251  	})
   252  	return trace.Wrap(err)
   253  }
   254  
   255  // DeleteAllAccessListMembersForAccessList hard deletes all access list members for an access list.
   256  func (c *Client) DeleteAllAccessListMembersForAccessList(ctx context.Context, accessList string) error {
   257  	_, err := c.grpcClient.DeleteAllAccessListMembersForAccessList(ctx, &accesslistv1.DeleteAllAccessListMembersForAccessListRequest{
   258  		AccessList: accessList,
   259  	})
   260  	return trace.Wrap(err)
   261  }
   262  
   263  // DeleteAllAccessListMembers hard deletes all access list members.
   264  func (c *Client) DeleteAllAccessListMembers(ctx context.Context) error {
   265  	return trace.NotImplemented("DeleteAllAccessListMembers is not supported in the gRPC client")
   266  }
   267  
   268  // UpsertAccessListWithMembers creates or updates an access list resource and its members.
   269  func (c *Client) UpsertAccessListWithMembers(ctx context.Context, list *accesslist.AccessList, members []*accesslist.AccessListMember) (*accesslist.AccessList, []*accesslist.AccessListMember, error) {
   270  	resp, err := c.grpcClient.UpsertAccessListWithMembers(ctx, &accesslistv1.UpsertAccessListWithMembersRequest{
   271  		AccessList: conv.ToProto(list),
   272  		Members:    conv.ToMembersProto(members),
   273  	})
   274  	if err != nil {
   275  		return nil, nil, trace.Wrap(err)
   276  	}
   277  
   278  	accessList, err := conv.FromProto(resp.AccessList, conv.WithOwnersIneligibleStatusField(resp.AccessList.GetSpec().GetOwners()))
   279  	if err != nil {
   280  		return nil, nil, trace.Wrap(err)
   281  	}
   282  
   283  	updatedMembers := make([]*accesslist.AccessListMember, len(resp.Members))
   284  	for i, member := range resp.Members {
   285  		var err error
   286  		updatedMembers[i], err = conv.FromMemberProto(member, conv.WithMemberIneligibleStatusField(member))
   287  		if err != nil {
   288  			return nil, nil, trace.Wrap(err)
   289  		}
   290  	}
   291  
   292  	return accessList, updatedMembers, nil
   293  }
   294  
   295  // AccessRequestPromote promotes an access request to an access list.
   296  func (c *Client) AccessRequestPromote(ctx context.Context, req *accesslistv1.AccessRequestPromoteRequest) (*accesslistv1.AccessRequestPromoteResponse, error) {
   297  	resp, err := c.grpcClient.AccessRequestPromote(ctx, req)
   298  	if err != nil {
   299  		return nil, trace.Wrap(err)
   300  	}
   301  	return resp, nil
   302  }
   303  
   304  // ListAccessListReviews will list access list reviews for a particular access list.
   305  func (c *Client) ListAccessListReviews(ctx context.Context, accessList string, pageSize int, pageToken string) (reviews []*accesslist.Review, nextToken string, err error) {
   306  	resp, err := c.grpcClient.ListAccessListReviews(ctx, &accesslistv1.ListAccessListReviewsRequest{
   307  		AccessList: accessList,
   308  		PageSize:   int32(pageSize),
   309  		NextToken:  pageToken,
   310  	})
   311  	if err != nil {
   312  		return nil, "", trace.Wrap(err)
   313  	}
   314  
   315  	reviews = make([]*accesslist.Review, len(resp.Reviews))
   316  	for i, review := range resp.Reviews {
   317  		var err error
   318  		reviews[i], err = conv.FromReviewProto(review)
   319  		if err != nil {
   320  			return nil, "", trace.Wrap(err)
   321  		}
   322  	}
   323  
   324  	return reviews, resp.GetNextToken(), nil
   325  }
   326  
   327  // ListAllAccessListReviews will list access list reviews for all access lists. Only to be used by the cache.
   328  func (c *Client) ListAllAccessListReviews(ctx context.Context, pageSize int, pageToken string) (reviews []*accesslist.Review, nextToken string, err error) {
   329  	resp, err := c.grpcClient.ListAllAccessListReviews(ctx, &accesslistv1.ListAllAccessListReviewsRequest{
   330  		PageSize:  int32(pageSize),
   331  		NextToken: pageToken,
   332  	})
   333  	if err != nil {
   334  		return nil, "", trace.Wrap(err)
   335  	}
   336  
   337  	reviews = make([]*accesslist.Review, len(resp.Reviews))
   338  	for i, review := range resp.Reviews {
   339  		var err error
   340  		reviews[i], err = conv.FromReviewProto(review)
   341  		if err != nil {
   342  			return nil, "", trace.Wrap(err)
   343  		}
   344  	}
   345  
   346  	return reviews, resp.GetNextToken(), nil
   347  }
   348  
   349  // CreateAccessListReview will create a new review for an access list.
   350  func (c *Client) CreateAccessListReview(ctx context.Context, review *accesslist.Review) (*accesslist.Review, time.Time, error) {
   351  	resp, err := c.grpcClient.CreateAccessListReview(ctx, &accesslistv1.CreateAccessListReviewRequest{
   352  		Review: conv.ToReviewProto(review),
   353  	})
   354  	if err != nil {
   355  		return nil, time.Time{}, trace.Wrap(err)
   356  	}
   357  	review.SetName(resp.ReviewName)
   358  	return review, resp.NextAuditDate.AsTime(), nil
   359  }
   360  
   361  // DeleteAccessListReview will delete an access list review from the backend.
   362  func (c *Client) DeleteAccessListReview(ctx context.Context, accessListName, reviewName string) error {
   363  	_, err := c.grpcClient.DeleteAccessListReview(ctx, &accesslistv1.DeleteAccessListReviewRequest{
   364  		AccessListName: accessListName,
   365  		ReviewName:     reviewName,
   366  	})
   367  	return trace.Wrap(err)
   368  }
   369  
   370  // DeleteAllAccessListReviews will delete all access list reviews from all access lists.
   371  func (c *Client) DeleteAllAccessListReviews(ctx context.Context) error {
   372  	return trace.NotImplemented("DeleteAllAccessListReviews is not supported in the gRPC client")
   373  }
   374  
   375  // GetSuggestedAccessLists returns a list of access lists that are suggested for a given request.
   376  func (c *Client) GetSuggestedAccessLists(ctx context.Context, accessRequestID string) ([]*accesslist.AccessList, error) {
   377  	resp, err := c.grpcClient.GetSuggestedAccessLists(ctx, &accesslistv1.GetSuggestedAccessListsRequest{
   378  		AccessRequestId: accessRequestID,
   379  	})
   380  	if err != nil {
   381  		return nil, trace.Wrap(err)
   382  	}
   383  
   384  	accessLists := make([]*accesslist.AccessList, len(resp.AccessLists))
   385  	for i, accessList := range resp.AccessLists {
   386  		var err error
   387  		accessLists[i], err = conv.FromProto(accessList)
   388  		if err != nil {
   389  			return nil, trace.Wrap(err)
   390  		}
   391  	}
   392  
   393  	return accessLists, nil
   394  }