requireWorkspaceOwnerExternalAuth returns a 403 response error when the workspace owner has not authenticated with every required (non-optional) external auth provider referenced by the template version. Token injection at build time uses the owner's external auth links, so the owner is the subject
(ctx context.Context, templateVersion database.TemplateVersion, ownerID uuid.UUID)
| 920 | // at build time uses the owner's external auth links, so the owner is the |
| 921 | // subject of the check even when another user initiates the build. |
| 922 | func (api *API) requireWorkspaceOwnerExternalAuth(ctx context.Context, templateVersion database.TemplateVersion, ownerID uuid.UUID) error { |
| 923 | //nolint:gocritic // System access is required to validate the workspace owner's external auth links because admins and API clients may create workspaces for other users. |
| 924 | providers, err := api.templateVersionExternalAuthForUser(dbauthz.AsSystemRestricted(ctx), templateVersion, ownerID) |
| 925 | if err != nil { |
| 926 | return err |
| 927 | } |
| 928 | |
| 929 | var ( |
| 930 | missingNames []string |
| 931 | validations []codersdk.ValidationError |
| 932 | ) |
| 933 | for _, provider := range providers { |
| 934 | if provider.Optional || provider.Authenticated { |
| 935 | continue |
| 936 | } |
| 937 | name := provider.DisplayName |
| 938 | if name == "" { |
| 939 | name = provider.ID |
| 940 | } |
| 941 | missingNames = append(missingNames, name) |
| 942 | validations = append(validations, codersdk.ValidationError{ |
| 943 | Field: "external_auth", |
| 944 | Detail: provider.ID, |
| 945 | }) |
| 946 | } |
| 947 | if len(missingNames) == 0 { |
| 948 | return nil |
| 949 | } |
| 950 | |
| 951 | return httperror.NewResponseError(http.StatusForbidden, codersdk.Response{ |
| 952 | Message: "External authentication is required to create a workspace with this template.", |
| 953 | Detail: fmt.Sprintf( |
| 954 | "The workspace owner must authenticate with the following external auth providers: %s.", |
| 955 | strings.Join(missingNames, ", "), |
| 956 | ), |
| 957 | Validations: validations, |
| 958 | }) |
| 959 | } |
| 960 | |
| 961 | func requestTemplate(ctx context.Context, req codersdk.CreateWorkspaceRequest, db database.Store) (database.Template, error) { |
| 962 | // If we were given a `TemplateVersionID`, we need to determine the `TemplateID` from it. |
no test coverage detected