Skip to content

Commit

Permalink
[v14] Add access request promotion state and suggestion API changes (#…
Browse files Browse the repository at this point in the history
…32710)

* Generate access list allowed promotions on access request creation (#31768)

* Generate access list suggestions on access request creation

* Add test
Cleanup code

* Add comment

* Fix typo and refactor access suggestion in services library

Fixed a typo in a comment in `access_list.go`. Refactored `accessrequest/suggestion.go` for enhanced code structure. The old model had all methods related to access request in a single interface, `accessRequestAPIGetter`, which had been divided among multiple interfaces for better division of responsibilities. A new function `GetSuggestedAccessLists` was created to narrow down the single duty for each function. These changes ensure more convenient unit testing and better accountability.

* Improve access request suggestions logic

This commit improves the logic for generating access request suggestions. It includes the requester's roles and traits as well as those from the access list and provides suggestions only for resource-based requests. A new method was also introduced for initializing AccessRequestSuggestions to avoid nil error.

* Refactor access list suggestions to promotions

The concept of 'suggestions' was updated to 'promotions' in different files (auth.go, client.go, auth_service_test.go, auth_service.proto among others) to make it more intuitive and align with the business context. This implies changing the wording, the functions called and the variable names. The feature itself hasn't changed, just the way it is referred.

* This commit changes the method name "GenerateAccessListSuggestions" to "GenerateAccessRequestPromotions" in multiple files. The naming is changed to reflect the actual function of the method, which is generating promotions for given access requests, rather than generating list suggestions. All relevant mentions and usages of this method are updated to reflect the name change. Modification also includes adjustments to the comments and interfaces related to the updated function for better code clarity.

* Refactor "GenerateAccessListSuggestions" to "GenerateAccessRequestPromotions"

Renamed method "GenerateAccessListSuggestions" to "GenerateAccessRequestPromotions" across the codebase. This change reflects the actual functionality of the method, which is to generate promotions for access requests, not suggestions. This aligns the method name with its purpose, and offers better code readability. Comments related to this function were also updated to maintain consistency.

* Update method handling access requests promotions

Revised the method of handling failures when generating access requests promotions. Now, even if promotions fail to generate, the request will not fail entirely. Instead, the request can still be approved but without promotions. Also, changed the UpsertAccessRequestAllowedPromotions method to CreateAccessRequestAllowedPromotions to clearly indicate its purpose, while revising related test cases and comments.

* Add 'promoted' access request state (#31346)

* This change introduces a new 'promoted' access request state. The state represents that an access request has been promoted to an access list.

Affected code was modified to adjust to the new promoted state and ensure correct system's behavior.

Added a new 'GetAccessRequest' method for internal use to retrieve access request info.
Disallowed direct promotion of access requests. Introduced 'SubmitAccessReviewAllowPromotion' for promotions.
Added 'PromoteAccessRequest' method and updated its usage to restrict direct promotions.
Refactored code for better readability and testing. Renamed some functions, simplified logic, added test helpers.
Introduced 'promoted' state for access requests to handle promotion workflow.
Added 'PromotedAccessListTitle' in 'AccessReview' to track promotion state.

* Refactor function and message names for better clarity

The function and message names related to the promotion of an access request to an access list were restructured for better readability and consistency. Names like 'PromoteAccessReqResponse'  have been replaced with more descriptive names such as 'PromoteAccessRequestResponse'. This increases clarity and consistency across the project.

* Remove the hacky GRPC server implementation

* Change method names to be more descriptive

Renamed all instances of 'PromoteAccessRequest' to 'AccessRequestPromote' in multiple files. The new method name provides a more descriptive and clear understanding of the method's function, which improves code readability and maintenance. This change applies to method definitions, comments, and error messages.

* Refine error message and introduce IsPromoted method

Refined the error message in 'access_request.go' to better indicate that only promoted requests can set the promoted access list title, not just have one. This enhances clarity of error message. Additionally, introduced 'IsPromoted' method in 'access_request.go' file. This method will be useful for quickly checking if a request is in the PROMOTED state.

* Rename variable in SubmitAccessReview method

Renamed the variable "params" to "submission" in the 'SubmitAccessReview' function, in 'auth_with_roles.go' file. The name "submission" provides clearer indictation of its role in submitting access review. This enhances code readability and understandability. No logic changes were made during this update.

* Add Access List title to access request. (#32618)

* Add Access List title to access request.

* Add test
Squash some bugs
  • Loading branch information
jakule authored Sep 29, 2023
1 parent 4d0f34d commit 76c8834
Show file tree
Hide file tree
Showing 36 changed files with 5,812 additions and 3,864 deletions.
9 changes: 9 additions & 0 deletions api/client/accesslist/accesslist.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,12 @@ func (c *Client) UpsertAccessListWithMembers(ctx context.Context, list *accessli

return accessList, updatedMembers, nil
}

// AccessRequestPromote promotes an access request to an access list.
func (c *Client) AccessRequestPromote(ctx context.Context, req *accesslistv1.AccessRequestPromoteRequest) (*accesslistv1.AccessRequestPromoteResponse, error) {
resp, err := c.grpcClient.AccessRequestPromote(ctx, req)
if err != nil {
return nil, trace.Wrap(err)
}
return resp, nil
}
11 changes: 11 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,17 @@ func (c *Client) DeleteAccessRequest(ctx context.Context, reqID string) error {
return trace.Wrap(err)
}

// GetAccessRequestAllowedPromotions returns the list of promotions allowed for the given access request.
func (c *Client) GetAccessRequestAllowedPromotions(ctx context.Context, req types.AccessRequest) (*types.AccessRequestAllowedPromotions, error) {
resp, err := c.grpc.GetAccessRequestAllowedPromotions(ctx, &proto.AccessRequestAllowedPromotionRequest{
AccessRequestID: req.GetName(),
})
if err != nil {
return nil, trace.Wrap(err)
}
return resp.AllowedPromotions, nil
}

// SetAccessRequestState updates the state of an existing access request.
func (c *Client) SetAccessRequestState(ctx context.Context, params types.AccessRequestUpdate) error {
setter := proto.RequestStateSetter{
Expand Down
2,027 changes: 1,222 additions & 805 deletions api/client/proto/authservice.pb.go

Large diffs are not rendered by default.

774 changes: 473 additions & 301 deletions api/gen/proto/go/teleport/accesslist/v1/accesslist_service.pb.go

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 21 additions & 1 deletion api/proto/teleport/accesslist/v1/accesslist_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ package teleport.accesslist.v1;
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "teleport/accesslist/v1/accesslist.proto";
import "teleport/legacy/types/types.proto";

option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1;accesslistv1";

// AccessLisetService provides CRUD methods for Access List resources.
// AccessListService provides CRUD methods for Access List resources.
service AccessListService {
// GetAccessLists returns a list of all access lists.
rpc GetAccessLists(GetAccessListsRequest) returns (GetAccessListsResponse);
Expand Down Expand Up @@ -60,6 +61,9 @@ service AccessListService {
rpc CreateAccessListReview(CreateAccessListReviewRequest) returns (CreateAccessListReviewResponse);
// DeleteAccessListReview will delete an access list review from the backend.
rpc DeleteAccessListReview(DeleteAccessListReviewRequest) returns (google.protobuf.Empty);

// AccessRequestPromote promotes an access request to an access list.
rpc AccessRequestPromote(AccessRequestPromoteRequest) returns (AccessRequestPromoteResponse);
}

// GetAccessListsRequest is the request for getting all access lists.
Expand Down Expand Up @@ -227,3 +231,19 @@ message DeleteAccessListReviewRequest {
// review_name is the name of the access list to delete.
string review_name = 1;
}

// AccessRequestPromoteRequest is the request for promoting an access request to an access list.
message AccessRequestPromoteRequest {
// RequestID is the unique ID of the request to be promoted.
string request_id = 1;
// AccessListName is the name of the access list to promote the request to.
string access_list_name = 2;
// Reason is the access request review reason.
string reason = 3;
}

// AccessRequestPromoteResponse is the response for promoting an access request to an access list.
message AccessRequestPromoteResponse {
// AccessRequest is the updated access request.
types.AccessRequestV3 access_request = 1;
}
17 changes: 16 additions & 1 deletion api/proto/teleport/legacy/client/proto/authservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2297,6 +2297,18 @@ message ExportUpgradeWindowsResponse {
string SystemdUnitSchedule = 3;
}

// AccessRequestAllowedPromotionRequest is the request to AccessRequestAllowedPromotion RPC call.
message AccessRequestAllowedPromotionRequest {
// AccessRequest is the access request to get promotions for.
string accessRequestID = 1;
}

// AccessRequestAllowedPromotionResponse is the response to AccessRequestAllowedPromotion RPC call.
message AccessRequestAllowedPromotionResponse {
// allowedPromotions is the list of allowed promotions for the access request.
types.AccessRequestAllowedPromotions allowedPromotions = 1;
}

// AuthService is authentication/authorization service implementation
service AuthService {
// InventoryControlStream is the per-instance stream used to advertise teleport instance
Expand Down Expand Up @@ -2394,9 +2406,12 @@ service AuthService {
rpc SetAccessRequestState(RequestStateSetter) returns (google.protobuf.Empty);
// SubmitAccessReview applies a review to a request and returns the post-application state.
rpc SubmitAccessReview(types.AccessReviewSubmission) returns (types.AccessRequestV3);
// GetAccessCapabilities requests the access capabilites of a user.
// GetAccessCapabilities requests the access capabilities of a user.
rpc GetAccessCapabilities(types.AccessCapabilitiesRequest) returns (types.AccessCapabilities);

// GetAccessRequestAllowedPromotions returns a list of allowed promotions from an access request to an access list.
rpc GetAccessRequestAllowedPromotions(AccessRequestAllowedPromotionRequest) returns (AccessRequestAllowedPromotionResponse);

// GetPluginData gets all plugin data matching the supplied filter.
rpc GetPluginData(types.PluginDataFilter) returns (PluginDataSeq);
// UpdatePluginData updates a plugin's resource-specific datastore.
Expand Down
8 changes: 8 additions & 0 deletions api/proto/teleport/legacy/types/events/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,14 @@ message AccessRequestCreate {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "max_duration,omitempty"
];

reserved "PromotedAccessListTitle";
reserved 14;

// PromotedAccessListName is the name of the access list that this request
// was promoted to.
// This field is only populated when the request is in the PROMOTED state.
string PromotedAccessListName = 15 [(gogoproto.jsontag) = "promoted_access_list_name,omitempty"];
}

// ResourceID is a unique identifier for a teleport resource. This is duplicated
Expand Down
40 changes: 40 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2054,6 +2054,15 @@ message AccessReviewThreshold {
uint32 Deny = 4 [(gogoproto.jsontag) = "deny,omitempty"];
}

// PromotedAccessList is a minimal access list representation used for
// promoting access requests to access lists.
message PromotedAccessList {
// Name is the name of the access list.
string Name = 1 [(gogoproto.jsontag) = "name"];
// Title is the title of the access list.
string Title = 2 [(gogoproto.jsontag) = "title"];
}

// AccessReview is a review to be applied to an access request.
message AccessReview {
// Author is the teleport username of the review author.
Expand Down Expand Up @@ -2081,6 +2090,13 @@ message AccessReview {
// ThresholdIndexes stores the indexes of thresholds which this review matches
// (internal use only).
repeated uint32 ThresholdIndexes = 7 [(gogoproto.jsontag) = "i,omitempty"];

reserved "PromotedAccessListTitle";
reserved 8;

// AccessList is the access list that this request was promoted to.
// This field is only populated when the request is in the PROMOTED state.
PromotedAccessList accessList = 9 [(gogoproto.jsontag) = "access_list,omitempty"];
}

// AccessReviewSubmission encodes the necessary parameters for submitting
Expand Down Expand Up @@ -2109,6 +2125,9 @@ enum RequestState {
// DENIED variant indicates that a request has been rejected by
// an administrating party.
DENIED = 3;
// PROMOTED variant indicates that a request has been promoted to
// an access list.
PROMOTED = 4;
}

// ThresholdIndexSet encodes a list of threshold indexes. One of the listed thresholds
Expand Down Expand Up @@ -2236,6 +2255,14 @@ message AccessRequestSpecV3 {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "session_ttl,omitempty"
];

reserved "PromotedAccessListTitle";
reserved 19;

// PromotedAccessListTitle is the title of the access list that this request
// was promoted to. Used by WebUI to display the title of the access list.
// This field is only populated when the request is in the PROMOTED state.
PromotedAccessList accessList = 20 [(gogoproto.jsontag) = "access_list,omitempty"];
}

// AccessRequestFilter encodes filter params for access requests.
Expand Down Expand Up @@ -2922,6 +2949,19 @@ message AccessReviewConditions {
repeated string PreviewAsRoles = 4 [(gogoproto.jsontag) = "preview_as_roles,omitempty"];
}

// AccessRequestAllowedPromotion describes an allowed promotion to an access list.
message AccessRequestAllowedPromotion {
// associated access list
string accessListName = 1;
}

// AccessRequestAllowedPromotions describes an valid promotion from an access request
// to an access list.
message AccessRequestAllowedPromotions {
// suggestions is a list of allowed access lists promotions.
repeated AccessRequestAllowedPromotion promotions = 1;
}

// ClaimMapping maps a claim to teleport roles.
message ClaimMapping {
// Claim is a claim name.
Expand Down
Loading

0 comments on commit 76c8834

Please sign in to comment.