Skip to content

Commit

Permalink
Add 'promoted' access request state (#31346)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
jakule authored Sep 26, 2023
1 parent 7f5387c commit e131370
Show file tree
Hide file tree
Showing 26 changed files with 3,180 additions and 2,604 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
}
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;
}
5 changes: 5 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,11 @@ message AccessRequestCreate {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "max_duration,omitempty"
];

// 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.
string PromotedAccessListTitle = 14 [(gogoproto.jsontag) = "promoted_access_list_title,omitempty"];
}

// ResourceID is a unique identifier for a teleport resource. This is duplicated
Expand Down
13 changes: 13 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,11 @@ message AccessReview {
// ThresholdIndexes stores the indexes of thresholds which this review matches
// (internal use only).
repeated uint32 ThresholdIndexes = 7 [(gogoproto.jsontag) = "i,omitempty"];

// 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.
string PromotedAccessListTitle = 8 [(gogoproto.jsontag) = "promoted_access_list_title,omitempty"];
}

// AccessReviewSubmission encodes the necessary parameters for submitting
Expand Down Expand Up @@ -2109,6 +2114,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 +2244,11 @@ message AccessRequestSpecV3 {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "session_ttl,omitempty"
];

// 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.
string PromotedAccessListTitle = 19 [(gogoproto.jsontag) = "promoted_access_list_title,omitempty"];
}

// AccessRequestFilter encodes filter params for access requests.
Expand Down
26 changes: 24 additions & 2 deletions api/types/access_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ type AccessRequest interface {
GetReviews() []AccessReview
// SetReviews sets the list of currently applied access reviews (internal use only).
SetReviews([]AccessReview)
// GetPromotedAccessListTitle returns the access list title that this access request
// was promoted to.
GetPromotedAccessListTitle() string
// SetPromotedAccessListTitle sets the access list title that this access request
// was promoted to.
SetPromotedAccessListTitle(string)
// GetSuggestedReviewers gets the suggested reviewer list.
GetSuggestedReviewers() []string
// SetSuggestedReviewers sets the suggested reviewer list.
Expand Down Expand Up @@ -304,6 +310,16 @@ func (r *AccessRequestV3) SetSuggestedReviewers(reviewers []string) {
r.Spec.SuggestedReviewers = reviewers
}

// GetPromotedAccessListTitle returns PromotedAccessListTitle.
func (r *AccessRequestV3) GetPromotedAccessListTitle() string {
return r.Spec.PromotedAccessListTitle
}

// SetPromotedAccessListTitle sets PromotedAccessListTitle.
func (r *AccessRequestV3) SetPromotedAccessListTitle(title string) {
r.Spec.PromotedAccessListTitle = title
}

// setStaticFields sets static resource header and metadata fields.
func (r *AccessRequestV3) setStaticFields() {
r.Kind = KindAccessRequest
Expand Down Expand Up @@ -603,11 +619,12 @@ func (s RequestStrategy) RequireReason() bool {

// stateVariants allows iteration of the expected variants
// of RequestState.
var stateVariants = [4]RequestState{
var stateVariants = [5]RequestState{
RequestState_NONE,
RequestState_PENDING,
RequestState_APPROVED,
RequestState_DENIED,
RequestState_PROMOTED,
}

// Parse attempts to interpret a value as a string representation
Expand Down Expand Up @@ -642,9 +659,14 @@ func (s RequestState) IsDenied() bool {
return s == RequestState_DENIED
}

// IsPromoted returns true is the request in the PROMOTED state.
func (s RequestState) IsPromoted() bool {
return s == RequestState_PROMOTED
}

// IsResolved request state
func (s RequestState) IsResolved() bool {
return s.IsApproved() || s.IsDenied()
return s.IsApproved() || s.IsDenied() || s.IsPromoted()
}

// key values for map encoding of request filter
Expand Down
Loading

0 comments on commit e131370

Please sign in to comment.