SetIamPolicy sets the IAM policy for a project.
(ctx context.Context, req *connect.Request[v1pb.SetIamPolicyRequest])
| 579 | |
| 580 | // SetIamPolicy sets the IAM policy for a project. |
| 581 | func (s *ProjectService) SetIamPolicy(ctx context.Context, req *connect.Request[v1pb.SetIamPolicyRequest]) (*connect.Response[v1pb.IamPolicy], error) { |
| 582 | projectID, err := common.GetProjectID(req.Msg.Resource) |
| 583 | if err != nil { |
| 584 | return nil, connect.NewError(connect.CodeInvalidArgument, err) |
| 585 | } |
| 586 | workspaceID := common.GetWorkspaceIDFromContext(ctx) |
| 587 | project, err := s.store.GetProject(ctx, &store.FindProjectMessage{ |
| 588 | Workspace: workspaceID, |
| 589 | ResourceID: &projectID, |
| 590 | }) |
| 591 | if err != nil { |
| 592 | return nil, connect.NewError(connect.CodeInternal, err) |
| 593 | } |
| 594 | if project == nil { |
| 595 | return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("project %q not found", req.Msg.Resource)) |
| 596 | } |
| 597 | if project.Deleted { |
| 598 | return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("project %q has been deleted", req.Msg.Resource)) |
| 599 | } |
| 600 | |
| 601 | oldIamPolicyMsg, err := s.store.GetProjectIamPolicy(ctx, workspaceID, project.ResourceID) |
| 602 | if err != nil { |
| 603 | return nil, connect.NewError(connect.CodeInternal, errors.Wrapf(err, "failed to find project iam policy with error")) |
| 604 | } |
| 605 | if req.Msg.Etag != "" && req.Msg.Etag != oldIamPolicyMsg.Etag { |
| 606 | return nil, connect.NewError(connect.CodeAborted, errors.Errorf("there is concurrent update to the project iam policy, please refresh and try again")) |
| 607 | } |
| 608 | |
| 609 | if err := validateIAMPolicy(ctx, s.store, !s.profile.SaaS, req.Msg, oldIamPolicyMsg); err != nil { |
| 610 | return nil, err |
| 611 | } |
| 612 | |
| 613 | policy, err := convertToStoreIamPolicy(req.Msg.Policy) |
| 614 | if err != nil { |
| 615 | return nil, err |
| 616 | } |
| 617 | |
| 618 | policyPayload, err := protojson.Marshal(policy) |
| 619 | if err != nil { |
| 620 | return nil, connect.NewError(connect.CodeInternal, err) |
| 621 | } |
| 622 | if _, err = s.store.CreatePolicy(ctx, &store.PolicyMessage{ |
| 623 | Workspace: workspaceID, |
| 624 | Resource: common.FormatProject(project.ResourceID), |
| 625 | ResourceType: storepb.Policy_PROJECT, |
| 626 | Payload: string(policyPayload), |
| 627 | Type: storepb.Policy_IAM, |
| 628 | InheritFromParent: false, |
| 629 | // Enforce cannot be false while creating a policy. |
| 630 | Enforce: true, |
| 631 | }); err != nil { |
| 632 | return nil, connect.NewError(connect.CodeInternal, err) |
| 633 | } |
| 634 | |
| 635 | iamPolicyMessage, err := s.store.GetProjectIamPolicy(ctx, workspaceID, project.ResourceID) |
| 636 | if err != nil { |
| 637 | return nil, connect.NewError(connect.CodeInternal, err) |
| 638 | } |
nothing calls this directly
no test coverage detected