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 }